2.8 常用的彙編指令
本節必須掌握的知識點:
彙編指令
多動手實驗,知道每個指令的功能
在此節之前彙編課程主要講了兩個問題,第一個問題是數據可以存哪?內存和寄存器。第二個問題是這些數據是如何存放的?我們介紹了兩種模式:一個是小端存儲,一個是大端存儲。如果要處理數據,我們就要使用匯編指令。什麼是彙編指令哪?在介紹彙編指令之前需要把它是什麼搞清楚。
2.8.1【彙編指令】
彙編指令是彙編語言中使用的一些操作符和助記符,還包括一些偽指令(如assume,end)。用於告訴【彙編程序】如何執行【彙編指令】,它既不控制機器的操作也不被彙編編成機器代碼,只能被彙編程序所識別並指導彙編如何執行。如圖2-8-1所示,用黑色框框選出來的,就是彙編區域,一行組合在一起就是彙編指令。
本節介紹MOV、LEA、ADD、SUB 、AND、 OR、 XOR、 NOT和XCHG指令。
【MOV指令】
圖2-8-1黑色框選區域中,有MOV DWORD PTR SS:[ESP+8],EBX;這條指令無非就是將EBX的數據移動到[ESP+8]對應的內存地址中去,大家可以反覆操作觀察。到目前為止,我們已經接觸了MOV指令。現在回顧一下MOV指令,MOV指令用於數據移動,既然是移動,那麼目的操作數的作用應該相當於一個“容器”,必須是具有大小範圍的內存單元或寄存器;源操作數也可以是和目的操作數具有相同數據寬度的通用寄存器和內存單元,也可以是立即數。移動的指令隻影響目的操作數的內容,不改變源操作數的內容。具體的指令格式如下:
1. MOV r/m8,r8 (r 通用寄存器)
2. MOV r/m16,r16(m代表內存)
3. MOV r/m32,r32(imm 代表立即數)
4. MOV r8,r/m8 (r8 代表8位通用寄存器)
5. MOV r16,r/m16(m8 代表8位內存)
6. MOV r32,r/m32(imm8 代表8位立即數)
7. MOV r8, imm8
8. MOV r16, imm16
9. MOV r32, imm32
【這些格式來源於Intel的白皮書,如果想詳細瞭解MOV或其他彙編指令有哪些形式和用法可以查詢Intel白皮書第2卷,第三章和第四章介紹的是彙編指令,所有的Intel的指令都在這裡,雖然Intel和AMD是不同的CPU,但是它們都遵循的是80X86架構,絕大多數的指令是一樣的。】
【LEA指令】
介紹了MOV指令,看圖2-8-1中有LEA指令,LEA指令和MOV指令一樣是移動數據,但是與MOV不同的是,它移動的是“[ ]”裡面的內容,例如:LEA EAX,[ECX]中,執行這條指令相當於MOV EAX,ECX。而MOV EAX,[ECX]是把“[ ]”裡面的數據當成是內存地址編號,取地址裡面的內容。
我們將MOV EAX,ECX,LEA EAX,[ECX]在軟件中編寫觀察。
第一步:輸入指令,如圖2-8-2所示,當前EAX存儲的數據為0x002D2BA2,ECA存儲的數據為0x00000000。
第二步:按F8一次觀察,如圖2-8-3所示。
第三步:由於EAX和ECX存儲的數據都一樣,我們改ECX存儲的數據,更改為0x11111111。
選中ECX存儲的數據0x00000000,右鍵彈出對話框,選擇Modify,彈出對話框如圖2-8-4所示,在黑色框選部分修改成0x11111111,如圖2-8-5所示。
第四步:按F8觀察,如圖2-8-6對比這兩條指令是否做著同樣的工作。
經過實驗表明,兩個指令幹了同一件事。自己動手實驗完成下面例題並觀察EAX與EDX裡面的數據是否相同,總結這些指令都做了什麼。
例:
MOV ECX,0x0012FF80 【0x0012FF80,該內存地址是已經申請過的,所以只要堆棧窗口中出現的內存地址,都可以使用】
MOV EAX,DWORD PTR DS:[ECX]
LEA EDX,DWORD PTR DS:[ECX]
LEA指令格式如下:
1、LEA r16,m16
2、LEA r32,m32
LEA指令它的源操作數只能是內存,目標操作數就只能是寄存器,不能操作8位數。
【ADD指令】
ADD表示“加”,“ADD 目標操作數,源操作數”:目標操作數+源操作數的結果保存在目標操作數中,舉例說明ADD EAX,0x00000004,我們在軟件中觀察EAX的變化。
第一步:輸入指令,為了方便觀察我們手動更改EAX寄存器的數據,更改為:0x00000000,如圖2-8-7所示。
第二步:按F8觀察,EAX存儲的數據的變化,如圖2-8-8所示。
F8單步執行完,我們看到了EAX存儲的數據發生了變化,變為了EAX原本存儲的數據+0x00000004的數據。這就是ADD指令的大致做的工作。
ADD指令格式如下:
1. ADD r/m8,r8
2. ADD r/m16,r16
3. ADD r/m32,r32
4. ADD r8,r/m8
5. ADD r16,r/m16
6. ADD r32,r/m32
7. ADD r8/m8,imm8
8. ADD r16/m16,imm16
9. ADD r32/m32,imm32
例:
自己動手實驗完成下面例題並觀察總結這些指令都做了什麼。
ADD EAX,ECX 寄存器到寄存器
ADD ECX,DWORD PTR DS:[0x0012FFC4] 內存到寄存器
ADD DWORD PTR DS:[0x0012FFC4],0x12 立即數到內存
【SUB指令】
SUB表示“減”,“SUB 目標操作數,源操作數”:目標操作數-源操作數的結果保存在目標操作數中,它的格式同MOV、ADD一樣。舉例說明SUB EAX,0x00000004,我們在軟件中觀察EAX的變化。
第一步:輸入指令,EAX當前存儲的數據為0x00000004如圖2-8-9所示。
第二步:按F8執行之後觀察EAX存儲的數據變化,如圖2-8-10所示。
F8單步執行完,我們看到了EAX存儲的數據發生了變化,變為了EAX原本存儲的數據-0x00000004的數據。這就是SUB指令的大致做的工作。
例:
自己動手實驗完成下面例題並觀察總結這些指令都做了什麼。
SUB EAX,ECX 寄存器到寄存器
SUB ECX,DWORD PTR DS:[0x0012FFC4] 內存到寄存器
SUB DWORD PTR DS:[0x0012FFC4],0x12 立即數到內存
【AND指令】
AND表示“與”,“AND 目標操作數,源操作數”:目標操作數與源操作數做“與運算”,結果保存在目標操作數中。
例:
自己動手實驗完成下面例題並觀察總結這些指令都做了什麼。
MOV AL, 0x01
AND AL, 0x10
【OR指令】
OR表示“或”,“OR 目標操作數,源操作數”:目標操作數與源操作數做“或運算”,結果保存在目標操作數中。
例:
自己動手實驗完成下面例題並觀察總結這些指令都做了什麼。
MOV AL, 0x11
OR AL, 0x10
【XOR指令】
XOR表示“異或”,“XOR 目標操作數,源操作數”:目標操作數與源操作數做“異或運算”,結果保存在目標操作數中。
例:
自己動手實驗完成下面例題並觀察總結這些指令都做了什麼。
MOV AL, 0x11
XOR AL, 0x11
【NOT指令】
這個指令和上面的指令有所區別,它的意思是對某個值求反,只涉及一個數,所以它的格式如下:
NOT r/m8
NOT r/m16
NOT r/m32
【XCHG指令】
CHG表示英文change,表示兩個容器交換數據,源操作數不能是立即數,主要功能將一個字節或一個字的源操作數和目的操作數相交換。
交換指令可以在寄存器之間,寄存器與存儲器之間進行,具體形式如下:
XCHG r8/m8,r8
XCHG r16/m16,r16
XCHG r32/m32,r32
XCHG r8,m8
XCHG r16,m16
XCHG r32,m32
自己動手實驗完成下面例題並觀察總結這些指令都做了什麼。
注意XCHG指令在使用時記住以下幾點:
1、不能同時都為內存操作數
2、任何一個操作數都不能為段寄存器
3、任何一個操作數不能為立即數
4、兩個操作數的長度必須相等
下節介紹內存複製。
練習:
1、已知EAX=0x00000008,ECX=0x0000000F,執行下面語句後,求EDX的數據
LEA EDX,DWORD PTR DS:[EAX+ECX]
2、已知EAX=0xFFFFFFFF,ESP=0x00000002,執行下面語句後,求EDX的數據
LEA EDX,DWORD PTR DS:[EAX+ESP*2]
3、已知EAX=01011100 ECX=11101111,EDX=11101110,執行下面語句後,求EDX的數據
LEA EDX,DWORD PTR DS:[EAX+ECX*2]
4、使用 MOV指令、ADD指令、SUB指令、AND指令、OR指令、XOR指令和 NOT指令 中的每一種格式做一個實驗觀察執行後的效果。(本節內容中已經把格式寫出來,主要目的是鍛鍊動手能力)。
閱讀更多 愛達人編程達人 的文章