彙編學習記錄之六

2021-09-01 13:03:42 字數 2975 閱讀 6411

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暫存器賦值,必須...