1. 程式人生 > >組合語言第六章總結

組合語言第六章總結

  • 在程式碼段中使用資料

assume cs:code
code segment
    dw 0123h,0456h,0789h,0abch,0fedh,0cbah,0987h
    
start:      mov bx,0
            mov ax,0
    
            mov cx,8
        s: add ax,cs:[bx]
            add bx,2
            loop s

            mov ax,4c00h
            int 21h
code ends
end start

    1.dw——定義字型資料,即define word(類似,db即為定義位元組資料)。

(這些資料的偏移地址分別為0、2、4、6、8、A、C、E,沒有標號start時,它們的段地址在CS中,因為這是一段程式碼段)

    2.標號start與end start——end除了通知編譯器程式結束外,還可以通知編譯器程式的入口在什麼地方,此處用end指令表明了程式的入口在標號start處,被轉化為一個入口地址。

    3.當程式被載入入記憶體之後,通過讀到程式的入口地址,設定CS:IP。

  • 在程式碼段中使用棧

assume cs:codesg
codesg segment
            dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h 
;用dw定義16個字型資料,在程式載入後,將取得16個字的記憶體空間,0~f,存放這16個數據 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;在此處預留了32個位元組作為棧,10~2f,在後面的程式將這段空間當作棧來使用 start: mov ax,cs mov ss,ax mov sp,30h ;將棧頂ss:sp指向cs:30h mov bx,0 mov cx,8 s: push cs:[bx] add bx,2 loop s
;將程式碼段0~15單元的8個字型資料依次入棧 mov bx,0 mov cx,8 s0: pop cs:[bx] add bx,2 loop s0 ;依次出棧8個字型資料到程式碼段0~15單元中 codesg ends end start

    1.注意:我們將cs:10~cs:2F的記憶體空間當作棧來用,初始狀態下為空,所以ss:sp要指向棧底,即cs:30h

  • 將資料、程式碼、棧放入不同的棧

    1.放在一個段的缺點:

        (1)把它們放到一個棧中使程式顯得混亂

        (2)若資料、棧和程式碼需要的空間超過64KB,就不能放在一個段中(一個段的容量不能大於64KB)

assume cs:code, ds:data, ss:stack
data segment
    dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends

stack segment
    dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends

code segment
start: mov ax,stack ;注意
         mov ss,ax
         mov sp,20h ;設定棧頂ss:sp指向stack:20

         mov ax,data  ;注意
         mov ds,ax     ;ds指向data段

         mov bx,0  ;ds:bx指向data段中的第一個單元
:
:(與上面程式碼相同,部分省略)

    2.一個段中的資料的段地址可由段名代表,在上例中data和stack這兩個段名就存入了相應的段暫存器中

    3.注意:

        (1)mov ds,data 是錯誤的,8086不允許將一個數值直接送入段暫存器中,在編譯器中將段名錶示為一個段地址的數值

        (2)用偽指令assume將cs、ds、ss分別和code、data、stack段相連之後,CPU也沒並沒有將對應的段和段暫存器相連線,因為assume只是偽指令

        (3)在源程式的最後用end start說明了程式的入口,CPU將會設定CS:IP,再執行裡面的指令mov ax,stack等和mov ax,data等時,才真正地實現了SS:SP、DS等的設定