1.源程式例子:
assume cs:codesg
codesg segment
start : mov ax, 0123h
mov bx, 0456h
add ax, bx
add ax, ax
mov ax, 4c00h
int 21h
codesg ends
end start
在組合語言源程式中,包含兩種指令,一種是彙編指令,一種是偽指令。
2.彙編指令
彙編指令是有對應的機器碼的指令,可以被編譯為機器指令,最終為cpu所執行。
例如:mov、add、sub等指令
3.偽指令
偽指令沒有對應的機器碼,不被cpu所執行,它是由編譯器來執行的指令,編譯器根據偽指令來進行相關的編譯工作。
上面的例子中出現了三種偽指令:
(3.1)segment指令和ends指令
segment和ends是一對成對使用的偽指令,這是在寫可被編譯器編譯的匯程式設計序時,必須使用到的一對偽指令。
segment和ends的功能是定義乙個段,segment說明乙個段開始,ends說明乙個段結束。乙個段必須有乙個名稱來標識,使用格式為:
段名 segment::
:段名 ends
比如上述例子中的:
codesg segment ;定義乙個段,段的名稱為"codesg",這個段從此開始。
:codesg ends ;名稱為"codesg"的段到此結束
乙個匯程式設計序是由多個段組成的,這些段被用來存放**、資料或者當作棧空間來使用。
前面學習的段的概念,在彙編源程式中得到了應用與體現,乙個源程式中所有將被計算機所處理的資訊:指令、資料、棧,被劃分到了不同的段中。
乙個有意義的匯程式設計序中至少要有乙個段,這個段用來存放**。
從上述例子中我們可以看到,在codesg segment和codesg ends之間寫的彙編指令是這個段中存放的內容,這是乙個**段。
(3.2)end 指令
end是乙個匯程式設計序的結束標記,編譯器在編譯彙編源程式的過程中,如果碰到了偽指令end,就結束對源程式的編譯。所以,在我們寫程式的時候,如果程式寫完了,要在結尾處加上偽指令end。否則,編譯器在編譯源程式時,無法知道程式在何處結束。
注意,還要搞混了end和ends,ends是和segment成對使用的,標記乙個段的結束,ends的含義可以理解為"end segment"。
我們在這裡講的end的作用是標記整個程式的結束。
(3.3)assume 指令
這條偽指令的含義是"假設",它假設某一段暫存器和程式中的某乙個用"segment ··· ends"定義的段相關聯。
通過assume說明這種關聯,在需要的情況下,編譯程式可以將段暫存器和某乙個具體的段相關聯。
assume並不是一條非要深入理解不可的偽指令,我們程式設計時記著用assume將有特定用途的段和相關的暫存器關聯起來即可。
比如,在上述例子中,我們用codesg segment ··· codesg ends定義了乙個名為codesg的段,在這個段中我們存放**,所以這個段是乙個**段。我們在程式的開頭,用assume cs:codesg將用作**段的段codesg和cpu中的段暫存器cs聯絡起來。
4.源程式中的"程式"
我們可以將源程式檔案中的所有內容稱為源程式,將源程式中最終由計算機執行、處理的指令或資料,稱為程式。程式最先以彙編指令的形式存在源程式中,經編譯、連線後轉變為機器碼,儲存在可執行檔案中。
5.標號
彙編源程式中,除了彙編指令和偽指令外,還有一些標號,比如"codesg"。乙個標號指代了乙個位址。比如codesg在segment前面,作為乙個段的名稱,這個段的名稱最終將被編譯、連線程式處理為乙個段位址。
6.程式的結構
彙編源程式是由一些段構成的。我們可以在這些段中存放**、資料或者將某個段當作棧空間來使用。
例如:
assume cs:code, ds:data, ss:stack
;定義"code"標號與**段暫存器cs相關聯
;定義"data"標號與資料段暫存器ds相關聯
;定義"stack"標號與棧段暫存器ss相關聯
data segment
dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
;在資料段中定義相關資料
data ends
stack segment
dw 0, 0, 0, 0, 0, 0, 0, 0
;在棧段中定義棧段空間大小
stack ends
code segment
;在**段中編寫彙編指令完成程式執行邏輯
start: mov ax, stack
mov ss, ax ;設定棧段暫存器ss指向stack段
mov sp, 16 ;設定棧頂指標ss:sp指向stack:16位置
mov ax, data
mov ds, ax ;設定資料段暫存器ds指向data段
mov bx, 0 ;設定ds:bx指向data段中的第乙個單元
push ds:[bx] ;將ds:[bx]中的內容入棧
pop ds:[bx] ;從棧中取出資料送入ds:[bx]指向的記憶體單元
mov ax, 4c00h
int 21h
code ends
end start
;在程式末尾新增end指令結束程式編譯
上述例子中分別定義了資料段、棧段和**段的標號,並且與相應的段暫存器相關聯,然後在程式開始後,先設定了棧段暫存器ss、棧頂指標sp和資料段暫存器ds,最後在程式結尾處新增了end指令。
這只是乙個非常簡陋的例子,沒有任何功能,只是演示了乙個彙編源程式的布局結構而已。
有錯誤請指正,謝謝!
彙編學習記錄之八
1.機器指令處理的資料所在位置 絕大部分機器指令都是進行資料處理的指令,處理大致可以分為三類 讀取 寫入 運算。在機器指令這一層來講,並不關心資料的值是多少,而關心指令執行前一刻,它將要處理的資料的所在位置。指令執行前,所要處理的資料可以在三個地方 cpu內部 記憶體 埠。2.組合語言中資料位置的表...
彙編學習記錄之十
1.轉移指令的原理 可以修改ip,或者同時修改cs和ip的指令統稱為轉移指令。概括地講,轉移指令就是可以控制cpu執行記憶體中某處的 的指令。8086cpu的轉移行為有以下幾類 1.1 只修改ip時,稱為段內轉移,比如 jmp ax 1.2 同時修改cs和ip時,稱為段間轉移,比如 jmp 1000...
彙編學習記錄
加粗樣式今天看到了驅動開發教程裡的中斷這一章了,結果課本直接先來一段組合語言,然而我早已把彙編忘得一乾二淨了,無奈只能重新再學一下了 cpsr是記錄當前的工作模式的狀態暫存器,在超級使用者模式下,可以用如下指令改變當前使用者模式 mov r3 0xd3 不能直接用立即數直接對cpsr暫存器賦值,必須...