三、常用匯編指令

7七柒發表於2024-10-30

MOV指令

作用:資料移動

image

mov cx,ax		// 將ax暫存器中的值複製到cx暫存器中
mov dx,FFFF		// 將資料0xFFFF放到暫存器dx中
mov al,bh		// 將bx暫存器的高八位的資料複製到ax暫存器的低八位

image

image

NOP:空指令

指令、資料對齊可以有效地提高程式的效能, 使用 NOP 指令,可以使得指令按字對齊,從而提高效率 。

比如一條指令佔用 3 個位元組,再加上一個 NOP 指令,就使得指令 4 位元組對齊了

運算指令

ADD指令:加

作用:加法

image

add ax,bx	// ax暫存器的值加上bx暫存器的值,結果放到ax暫存器中
add bx,ff	// bx暫存器的值加上0xff,結果放到bx暫存器中
add cl,11	// cx暫存器的低8位加上0x11,結果放到cx暫存器的低八位裡面

image

注意:假設計算的結果超過了暫存器的位數時,多出來的高位會被捨棄。或者說當計算的值超過超過暫存器可容納的最大值(16位暫存器最大值是0xFF)後,暫存器會從0開始計算(0xffff+1 = 0;0xffff+2 = 1)

例如:0xCDEF + 0xEFDD = 0x1BDCC

但是暫存器只會保留0xBDCC,如下圖

image

只計算低八位的需要進位時,也不會向高位進位,會直接捨棄

SUB指令:減

作用:減法

image

注意:當被減數小於減數時,被減數會向前借位。或者說被減數被減到0x00後,再減就會變成0xff

示例:

sub ax,bx	// ax暫存器減去bx暫存器,結果放到ax暫存器中
sub bx,33	// bx暫存器減去0x33,結果放到bx暫存器中
sub cl,bh	// cx暫存器的低八位減去bx暫存器的高八位,結果放到cx暫存器的低八位

image

MUL指令:乘

作用:乘法

注意:

  1. 兩個相乘的數:兩個相乘的數,要麼都是8位,要麼都是16位。如果是8位,一個預設放在AL中,另一個放在8位reg或記憶體位元組單元中;如果是16位,一個預設在AX中,另一個放在16位reg或記憶體字單元中。

  2. 結果:如果是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暫存器中
    

    image

  • 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
    

    image

DIV指令:除

作用:除法

注意:

  1. 除數:有8位和16位兩種,在一個reg或記憶體單元中。
  2. 被除數:預設放在AX或DX和AX中,如果除數為8位,被除數則為16位,預設在AX中存放;如果除數為16位,被除數則為32位,在DX和AX中存放,DX存放高16位,AX存放低16位。
  3. 結果:如果除數為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
    

    image

  • 16位除法:305419896 / 61166 = 4993 ... 18058 (0x12345678 / 0xEEEE)

    mov dx,1234		// 設定被除數的高16位
    mov ax,5678		// 設定被除數的低16位
    mov bx,eeee		// 設定除數
    div bx			// 相除。結果的商放在ax,餘數放在dx
    

    image

AND指令:與

作用:按位與運算

示例:0x4f與0xef進行與運算

mov al,4f	
and al,fe	// al的值按位與0xfe,結果放到al中

image

OR指令:或

作用:按位或運算

示例:0xac與0x01進行或運算

mov al,ac
or al,01	// al的值按位或0x01,結果放到al中

image

SHL指令:左移

作用:普通左移,將最後移出的一位寫入:CF中,低位補0

注意:如果移動的位數大於1,則必須將移動位數放到cl中

示例:

  • 移動一位

    0xffff左移一位

    mov ax,ffff
    shl ax,1		// ax的值左移一位,結果放到ax中
    

    image

  • 移動多位

    0xffff左移3位

    mov ax,ffff
    mov cl,3	// 要移動的位數大於1時,要放到cl中
    shl ax,cl	// ax的值左移3位,結果放到ax中
    

    image

SHR指令:右移

作用:普通右移,將最後移出的一位寫入:CF中,高位補0

注意:如果移動的位數大於1,則必須將移動位數放到cl中

與左移同理,只不過移動的方向相反

ROL指令:不帶進位的迴圈左移

作用:向左移,最後移出來的一位寫入CF中,並且回到最低位

image

注意:如果移動的位數大於1,則必須將移動位數放到cl中

示例:

  • 0x80向左移動一位

    mov al,80	
    rol al,1	// al中的值迴圈左移一位,結果放到al中
    

    image

  • 0x80向左移動4位(交換高四位和第四位)

    mov al,80
    mvo cl,4	// 要移動的位數放到cl中
    rol al,cl	// al的值迴圈左移4次,結果放到al中
    

    image

ROR指令:不帶進位的迴圈右移

作用:向右移,最後移出來的一位寫入CF中,並且回到最高位

注意:如果移動的位數大於1,則必須將移動位數放到cl中

其他與迴圈左移同理

RCL指令:帶進位的迴圈左移

作用:左移, 將CF位放到目標運算元的最左邊,一起參與迴圈,從CF位移出去的數字迴圈回最低位

image

注意:如果移動的位數大於1,則必須將移動位數放到cl中

示例:

0x80帶進位迴圈左移兩次

mov al,80
rcl al,1
rcl al,1

image

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中

image

INC指令:自增

作用:自增

注意:超過最大值後會歸零,或者說向前進了一位,但是進的位被捨棄了

示例:

mov al,fc
inc al		// al的值自增1,結果放到al中
inc al		// al的值自增1,結果放到al中

image

DEC指令:自減

作用:自減

注意:等於0後還減會等於最大值,或者說向前借了一位

示例:

mov al,01
dec al		// al的值自減1,結果放到al中
dec al		// al的值自減1,結果放到al中

image

XCHG指令:交換值

作用: 交換兩個資料的內容

注意:

  • 不能交換兩個記憶體運算元,只能暫存器與暫存器,暫存器與記憶體運算元。如果要交換兩個記憶體運算元,需要用暫存器做臨時容器,mov和xchg一起使用
  • 兩個交換的數的大小必須一致,8位和8位交換,16位和16位交換,不能8位和16位交換

示例:交換ax和bx

mov ax,1111
mov bx,2222
xchg ax,bx		// 交換ax和bx

image

相關文章