作者:bakari 時間:2012.4.21
1、 操作數類型
Imm立即操作數
Reg寄存器操作數
Mem記憶體操作數
2、 操作數尋址方式
立即數尋址
寄存器數尋址
存儲器尋址
3、 資料傳送類指令
(重點介紹)mov、xchg、push、pop、lea
(除标志寄存器指令外,其餘均不影響标志位)
1.1、 通用資料傳送指令
1)、Mov傳送指令
兩個操作數的尺寸必須是一緻的(但movzx和movsx例外)
兩個操作數不能同時為記憶體操作數(記憶體資料不能直接傳送)
指令規則 目的操作數不能為CS、EIP和IP(會覆寫原來其指向的數)
立即數不能直接送段寄存器(不允許:mov DS ,Data)
兩個段寄存器之間不能直接傳送資料
(其餘指令與此類似)
MOVSX:符号擴充
MOVZX:零擴充
8位或16位擴充為32位,兩個操作數的尺寸不一緻,目的操作數是寄存器
補充:記憶體内偏移位址的應用 見一段代碼:
.data
var1 BYTE 10h
.code
Mov al , var1
方括号:[ ]:可用符号位址代替數值位址(var1是一個符号位址)
Var1 BYTE 10h,20h,30h
Mov al , [var1+2] ;=mov al , var1+2 ;al=30h
2)、交換指令XCHG :
----------------------------見一段指令----------------------
Mov ax,var1
Xchg ax,var2
Mov var2,ax
1.2、 堆棧操作指令(移動位址遵循低對低,高對高的原則)
1)、進棧指令:push指令 ESP指定棧頂的偏移位址
ESP逐漸減少(記憶:把堆棧想象成一個倒扣的桶,棧底是高位址,進棧資料增多ESP下移)
Push指令隻表達源操作數,目的操作數在棧頂,由ESP确定。
---------------------見一段代碼---------------------
;進棧指令
Push eax ;等同于如下兩條指令
Sub esp,4 ;減法指令
Mov [esp],eax ;傳送指令
2)出棧指令:pop指令
ESP逐漸增多
源操作數在棧頂由ESP确定,pop指令隻表達目的操作數,剛好與push指令相反
----------------------用法見一段指令-----------------
;出棧指令
Pop eax ;等同于如下兩條指令
Mov eax , [esp] ;傳送指令
Add esp , 4 ;加法指令
-----------------------綜合:見一段堆棧操作程式-----------------------
Ten = 10
Dvar DEORD 67762000h , 12345678h
Mov eax , dvar+4 ;eax=12345678h
Push eax ;将eax裡的内容壓入堆棧
Push DWORD ptr ten ;将立即數以雙字量壓入堆棧
Push dvar ;将變量的第一個資料壓入堆棧
Pop eax ;将棧頂資料彈出到eax
Pop dvar+4 ;棧頂資料彈出到DVAR+4的位置
Mov ebx , dvar+4 ;ebx=0000000AH
Pop ecx ;棧頂資料彈出到ecx
應用堆棧的幾點注意以及應用
1、 注意:
-------------由于堆棧的棧頂和内容随着程式的執行不斷變化,是以程式設計時應該注意進棧和出棧的資料要成對,要保持堆棧平衡。
--------------避免16和32為兩種傳送機關的混用。
2、 應用
-------------堆棧指令、子程式調用指令CALL、子程式反回RET指令、中斷調用INT指令、中斷傳回IRET等指令都會使用堆棧,修改ESP值。
-------------用來存放資料,以便随時恢複它們,使用pop指令時明确棧頂的資料。
-------------可以以随機的方式讀取其中的資料,EBP就是以這個目的而設計(見一段代碼)
Mov ebp , esp
Mov eax , [ebp+8]
Mov [ebp] , eax
------------利用堆棧實作主程式與子程式間的傳遞參數
------------還常用于子程式的寄存器保護和恢複,進行快速的現場保護和恢複。
1.3、 其他傳送指令
1)、位址傳送指令:lEA
-----------------------LEA 的一點重點-----------------------------
-LEA與offset的差別
LEA:CPU的指令,後面課跟标号、常量和表達式
Offset:僞指令,後面隻能跟标号和常量
------------見一段代碼
Buffer dp 100 dup ( 0 ) ;開辟100個連續位元組的的初始化為零的空間
;dp 與WORD,BYTE形式類似
;buffer 類似數組名,指向的是數組的首位址
Lea ebx , buffer ;(送首位址)
Mov ebx , offset buffer ;(送位址)
Mov ebx , buffer ;(送第一個數 零)
Lea ebx , [buffer+50] ;(送地51個位址)
Mov enx ,offset [buffer+50] ;ERROR!(buffer+50已經是位址,offset有送位址,亂套了!)
一般來說:注意:
mov reg , offset XXX 比 Lea reg , XX 的指令長度少一個位元組,快一個時鐘,但lea更靈活