彙編學習記錄之四
資料來源:組合語言第二版-王爽
1.mov,add,sub指令
mov指令有以下幾種形式:
mov 暫存器,資料 比如:mov ax, 8
mov 暫存器,暫存器 比如:mov ax, bx
mov 暫存器,記憶體單元 比如:mov ax, ds:[0]
mov 記憶體單元,暫存器 比如:mov ds:[0], ax
mov 記憶體單元,段暫存器 比如:mov ds:[0], cs
mov 段暫存器,記憶體單元 比如:mov cs, ds:[0]
mov 段暫存器,暫存器 比如:mov ds, ax
mov 暫存器,段暫存器 比如:mov ax, cs
add和sub指令同mov指令一樣,都有兩個操作物件。它們也可以有以下幾種形式:
add 暫存器,資料 比如:add ax, 8
add 暫存器,暫存器 比如:add ax, bx
add 暫存器,記憶體單元 比如:add ax, ds:[0]
add 記憶體單元,暫存器 比如:add ds:[0], ax
sub 暫存器,資料 比如:sub ax, 8
sub 暫存器,暫存器 比如:sub ax, bx
sub 暫存器,記憶體單元 比如:sub ax, ds:[0]
sub 記憶體單元,暫存器 比如:sub ds:[0], ax
2.棧
8086CPU中,ss是棧段暫存器,sp是棧頂指標暫存器,棧頂的段地址存放在ss中,偏移地址存放在sp中。
任意時刻,ss:sp指向棧頂元素。
棧有兩個基本操作:入棧(push)和出棧(pop)。
puss指令和pop指令執行時,CPU從ss和sp中得到棧頂的位置。
入棧就是將一個新的元素放到棧頂,出棧就是從棧頂取出一個元素。
棧的操作規則為:LIFO(Last In First Out,後進先出)
push ax //表示將通用暫存器ax中的資料送入棧中
pop ax //表示從棧頂取出資料送入通用暫存器ax中
push ax的執行,由以下兩步完成:
(1)sp=sp-2,ss:sp指向當前棧頂前面的單元,以當前棧頂前面的單元為新的棧頂;
(2)將通用暫存器ax中的內容送入ss:sp指向的記憶體單元處,ss:sp此時指向新的棧頂。
pop ax的執行過程和push ax剛好相反,由以下兩步完成:
(1)將ss:sp指向的內容單元處的資料送入通用暫存器ax中;
(2)sp=sp+2,ss:sp指向當前棧頂下面的單元,以當前棧頂下面的單元為新的棧頂。
3.push和pop指令的格式可以是如下形式:
push 暫存器 比如:push ax 入棧,將通用暫存器ax中的資料放入棧中
pop 暫存器 比如:pop ax 出棧,用通用暫存器ax接收從棧中取出的資料
push 段暫存器 比如:push ds 入棧,將段暫存器ds中的資料放入棧中
pop 段暫存器 比如:pop ds 出棧,用段暫存器ds接收從棧中取出的資料
push 記憶體單元 比如:push ds:[0] 入棧,將記憶體單元ds:[0]中的資料放入棧中
pop 記憶體單元 比如:pop ds:[0] 出棧,用記憶體單元ds:[0]接收從棧中取出的資料
4.push、pop實質上是一種記憶體傳送指令,注意它們的靈活應用。
5.棧段的大小為16的倍數
一個棧空間中有N個位元組,則這個棧段的空間大小為:16 * (N / 16 + 1)
6.棧頂超界問題
8086CPU只記錄棧頂,棧空間的大小需要我們自己管理。
我們在程式設計的時候要自己操心棧頂超界的問題,要根據可能用到的最大棧空間,來安排棧的大小,防止入棧的資料太多而導致的超界;執行出棧操作的時候也要注意,以防棧空的時候繼續出棧而導致的超界。
ss指示棧段段地址,sp指示當前棧頂指標,CPU只會根據棧的操作指令進行資料的讀寫,所以越界訪問有可能會出現未知錯誤。
有錯誤請指正,謝謝。