MOV指令
作用:資料移動
mov cx,ax // 將ax暫存器中的值複製到cx暫存器中
mov dx,FFFF // 將資料0xFFFF放到暫存器dx中
mov al,bh // 將bx暫存器的高八位的資料複製到ax暫存器的低八位
NOP:空指令
指令、資料對齊可以有效地提高程式的效能, 使用 NOP 指令,可以使得指令按字對齊,從而提高效率 。
比如一條指令佔用 3 個位元組,再加上一個 NOP 指令,就使得指令 4 位元組對齊了
運算指令
ADD指令:加
作用:加法
add ax,bx // ax暫存器的值加上bx暫存器的值,結果放到ax暫存器中
add bx,ff // bx暫存器的值加上0xff,結果放到bx暫存器中
add cl,11 // cx暫存器的低8位加上0x11,結果放到cx暫存器的低八位裡面
注意:假設計算的結果超過了暫存器的位數時,多出來的高位會被捨棄。或者說當計算的值超過超過暫存器可容納的最大值(16位暫存器最大值是0xFF)後,暫存器會從0開始計算(0xffff+1 = 0;0xffff+2 = 1)
例如:0xCDEF + 0xEFDD = 0x1BDCC
但是暫存器只會保留0xBDCC,如下圖
只計算低八位的需要進位時,也不會向高位進位,會直接捨棄
SUB指令:減
作用:減法
注意:當被減數小於減數時,被減數會向前借位。或者說被減數被減到0x00後,再減就會變成0xff
示例:
sub ax,bx // ax暫存器減去bx暫存器,結果放到ax暫存器中
sub bx,33 // bx暫存器減去0x33,結果放到bx暫存器中
sub cl,bh // cx暫存器的低八位減去bx暫存器的高八位,結果放到cx暫存器的低八位
MUL指令:乘
作用:乘法
注意:
-
兩個相乘的數:兩個相乘的數,要麼都是8位,要麼都是16位。如果是8位,一個預設放在AL中,另一個放在8位reg或記憶體位元組單元中;如果是16位,一個預設在AX中,另一個放在16位reg或記憶體字單元中。
-
結果:如果是8位乘法,結果預設放在AX中:如果是16位乘法,結果高位預設在DX中存放,低位在AX中放。
示例:
-
2個8位數相乘(小於255):0x64 * 0x0a = 0x03e8 (100 * 10)
mov al,64 // ax暫存器低八位設定為0x64 mov bx,a // bx暫存器設定為0x0a mul bx // bx暫存器的值乘以al暫存器的值,結果放到ax暫存器中
-
2個16位數相乘:0x03e8 * 0x03e8= 0xF4240 (1000*1000)
mov ax,3e8 // ax暫存器設定為0x3e8 mov bx,3e8 // bx暫存器設定為0x3e8 mul bx // ax的值乘以bx的值,結果的高16位放到dx,低16位放到ax
DIV指令:除
作用:除法
注意:
- 除數:有8位和16位兩種,在一個reg或記憶體單元中。
- 被除數:預設放在AX或DX和AX中,如果除數為8位,被除數則為16位,預設在AX中存放;如果除數為16位,被除數則為32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
- 結果:如果除數為8位,則AL儲存除法操作的商,AH儲存除法操作的餘數:如果除數為16位,則AX儲存除法操作的商,DX儲存除法操作的餘數。
示例:
-
8位除法:23 / 5 = 4 ... 3 (0x17 / 0x05)
mov ax,17 // 設定被除數為0x17 mov bl,5 // 設定除數為8位的0x05 div bl // 計算0x17 / 0x05。結果的商在al,餘數在ah
-
16位除法:305419896 / 61166 = 4993 ... 18058 (0x12345678 / 0xEEEE)
mov dx,1234 // 設定被除數的高16位 mov ax,5678 // 設定被除數的低16位 mov bx,eeee // 設定除數 div bx // 相除。結果的商放在ax,餘數放在dx
AND指令:與
作用:按位與運算
示例:0x4f與0xef進行與運算
mov al,4f
and al,fe // al的值按位與0xfe,結果放到al中
OR指令:或
作用:按位或運算
示例:0xac與0x01進行或運算
mov al,ac
or al,01 // al的值按位或0x01,結果放到al中
SHL指令:左移
作用:普通左移,將最後移出的一位寫入:CF中,低位補0
注意:如果移動的位數大於1,則必須將移動位數放到cl中
示例:
-
移動一位
0xffff左移一位
mov ax,ffff shl ax,1 // ax的值左移一位,結果放到ax中
-
移動多位
0xffff左移3位
mov ax,ffff mov cl,3 // 要移動的位數大於1時,要放到cl中 shl ax,cl // ax的值左移3位,結果放到ax中
SHR指令:右移
作用:普通右移,將最後移出的一位寫入:CF中,高位補0
注意:如果移動的位數大於1,則必須將移動位數放到cl中
與左移同理,只不過移動的方向相反
ROL指令:不帶進位的迴圈左移
作用:向左移,最後移出來的一位寫入CF中,並且回到最低位
注意:如果移動的位數大於1,則必須將移動位數放到cl中
示例:
-
0x80向左移動一位
mov al,80 rol al,1 // al中的值迴圈左移一位,結果放到al中
-
0x80向左移動4位(交換高四位和第四位)
mov al,80 mvo cl,4 // 要移動的位數放到cl中 rol al,cl // al的值迴圈左移4次,結果放到al中
ROR指令:不帶進位的迴圈右移
作用:向右移,最後移出來的一位寫入CF中,並且回到最高位
注意:如果移動的位數大於1,則必須將移動位數放到cl中
其他與迴圈左移同理
RCL指令:帶進位的迴圈左移
作用:左移, 將CF位放到目標運算元的最左邊,一起參與迴圈,從CF位移出去的數字迴圈回最低位
注意:如果移動的位數大於1,則必須將移動位數放到cl中
示例:
0x80帶進位迴圈左移兩次
mov al,80
rcl al,1
rcl al,1
RCR指令:帶進位的迴圈右移
作用:右移,將CF位放到目標運算元的最右邊,一起參與迴圈,從CF位移出去的數字迴圈回最高位
注意:如果移動的位數大於1,則必須將移動位數放到cl中
其他與帶進位迴圈左移同理
NEG指令:求補
作用: 求補運算,即用零減去運算元,然後將結果返回給運算元。這個過程也可以理解為將運算元按位取反後再加1。NEG指令通常用於求一個數的相反數,也就是它的補碼。
NEG指令的工作原理:
-
按位取反加一:首先,將運算元轉換為補碼錶示,然後按位取反,最後在末位加1。例如,如果運算元是正數64h(二進位制0110 0100),按位取反後得到1001 1011,再加1得到1001 1100,即9ch,這就是-64h的補碼錶示。
-
從運算角度:可以將NEG指令看作是0減去運算元的運算。例如,如果運算元是64h,那麼
neg al
相當於0 - 64h = -64h
。如果運算元是-8,那麼neg al
相當於0 - (-8) = 8
。這種方法對於運算元為負數的情況更為簡便,相當於直接求絕對值。
示例:對0xff08求補
mov ax,ff08
neg ax // 對ax中的值求補,結果放到ax中
INC指令:自增
作用:自增
注意:超過最大值後會歸零,或者說向前進了一位,但是進的位被捨棄了
示例:
mov al,fc
inc al // al的值自增1,結果放到al中
inc al // al的值自增1,結果放到al中
DEC指令:自減
作用:自減
注意:等於0後還減會等於最大值,或者說向前借了一位
示例:
mov al,01
dec al // al的值自減1,結果放到al中
dec al // al的值自減1,結果放到al中
XCHG指令:交換值
作用: 交換兩個資料的內容
注意:
- 不能交換兩個記憶體運算元,只能暫存器與暫存器,暫存器與記憶體運算元。如果要交換兩個記憶體運算元,需要用暫存器做臨時容器,mov和xchg一起使用
- 兩個交換的數的大小必須一致,8位和8位交換,16位和16位交換,不能8位和16位交換
示例:交換ax和bx
mov ax,1111
mov bx,2222
xchg ax,bx // 交換ax和bx