16位彙編 03
>> 資料傳送類指令
1:傳送指令MOV(move)
把一個位元組或者運算元從原地址傳送到目的地址。
注意:
1.立即數不能作為目的運算元,如mov 110H,AX
2.立即數不能直接傳給段暫存器,如mov DS,110H // 翻譯成機器碼很長
2.兩個運算元不能同時為段暫存器,如mov ES,DS // 可通過Ax暫存器間接傳遞
3.兩個運算元不能同時為儲存單元,如mov [0x1245],[0x1312] // 翻譯成機器碼很長
5.程式碼段暫存器CS不能為目的運算元,但可為源運算元 // CS為存放程式碼段的段地址,是程式碼段暫存器。它與IP共用,以指示下一條要執行的指令,不能隨意更改!
6.指令指標IP不能作為mov指令的運算元
mov指令參考資料:
mov是彙編中的傳送指令。
mov 位寬 目的運算元,源運算元
在mov傳送指令中的目的運算元或源運算元,只要涉及記憶體地址的都是邏輯地址,彙編程式中的每一條指令地址都是一個相對於程式碼段頭部的偏移地址,這個地址叫做彙編地址。當程式載入到記憶體後就會有一個真實的起始地址,這個地址會給CS段暫存器。CPU執行指令就是會按CS:IP去尋找指令,此時你會發現IP偏移地址跟彙編地址是一樣的,因為它們都是相對於程式起始位置的偏移。
位寬:目的運算元和源運算元的位寬要一致。否則程式會有問題。
這裡的位寬是一個位元組,位寬可以是一個位元組,單字(2個位元組),雙字(4個位元組),四字(8個位元組)。有些mov的傳送指令沒有指定位寬,因為有些位寬是顯而易且一致的。如通用暫存器之間的傳送,就可以不指定位寬。但要切忌要保證兩個暫存器的位寬一致。
目的運算元必需是一個容器,如記憶體單元、暫存器。
源運算元可以是一個立即數,也可以是一個容器。
容器有記憶體單元、通用暫存器(AX、BX、CX、DX等)、段暫存器(CS、DS)
立即數就是指令中指定的長度為16位的2的補碼,如0xb800
立即數只能用作源運算元,也就是它只能傳給容器,如記憶體單元目的運算元,通用暫存器。但是,不能傳給段暫存器,原因也很簡單,段寄存可是記錄記錄程式碼段或資料段的起始地址,豈能隨便修改。立即數不能作為目的運算元。
段暫存器雖然不能直接用立即數來設定,但是可以通過通用暫存器或記憶體單元業間接設定,同時段暫存器中的內容也可以傳送到這兩個地方。段暫存器之間不能互相傳遞,即mov cs,ds是錯的,且這樣設定也是沒有意義的,因為兩個都是記錄某個段的起始位置的,不可能在一塊,且它們都有專門的用途。
通用暫存器除了不能傳遞給立即數,它可向記憶體單元和暫存器傳值。通用暫存器之間可以互相傳,它還可接受段暫存器和記憶體單元的內容。
記憶體單元可以接受來自立即數、通用暫存器、段暫存器的內容,但是記憶體單元雖然是容器,但是mov傳送指令不能夠將一個記憶體單元的內容傳送到另一個記憶體單元。
>> 交換指令XCHG(exchange)
情形:
1:暫存器與暫存器之間交換
2:暫存器與儲存器之間交換
3:不能在儲存器與儲存器之間交換資料
效率:
XCHG優於MOV, 因為xchg使用了內部暫存器
舉例:
1:AH, AL 高低位交換
2:儲存器【2040】與【2050】交換
>> 換碼指令XLAT
作用:將BX指定的緩衝區中, AL移出一個位元組取出賦給AL.
即:al <--ds:[bx + al]
該指令無運算元
用途:鍵盤的掃描碼, 需要轉為ASCII碼,
可以將掃描碼做成表, 掃描碼作下標可以查到對應的ASCLL碼
這條指令也叫累加器專用指令
>> 堆疊操作指令
1:壓棧(push reg)把一個運算元存入棧中,該運算元從暫存器中或者記憶體中取,運算元必須是16位2位元組
每次往棧中存入一個值, 棧頂上升, sp(堆疊指標暫存器)中存的值減2, ss(堆疊段暫存器)中存了棧底的地址(堆疊段基址)
2:彈棧(pop reg)把棧中從棧頂開始的數, 彈到指定地址, 可以是暫存器,也可以是記憶體, 彈出一個數, sp中的值加2
3:儲存所有暫存器環境
16位: pusha / popa
32位:pushad / popad
>> 標誌暫存器傳送指令
四條指令
>> 地址傳送指令
** 將儲存單元的EA送至指定暫存器
——有效地址傳送指令LEA(load EA)
注意: 不是獲取儲存單元的內容
一般用作2個以上數值的加法
——指標傳送指令LDS和LES
>> 算數運算類指令
>> 加法
add
adc
>> 減法
sub
sbb
>> 求補指令
NEG
>> 比較指令
CMP:
兩個運算元相減, 結果不儲存, 但是影響標誌位
運算元不變