彙編學習記錄之六

資料來源:彙編語言第二版-王爽

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指令。

這只是一個非常簡陋的例子,沒有任何功能,只是演示了一個彙編源程序的佈局結構而已。

 

 

有錯誤請指正,謝謝!    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章