1. 程式人生 > 實用技巧 >80x86指令系統-1-資料傳送指令

80x86指令系統-1-資料傳送指令

80x86的指令系統

80x86的指令系統可以分為以下6組:

資料傳輸指令 傳處理指令

算術指令 控制轉移指令

邏輯指令 處理機控制指令

資料傳送指令

負責把資料、地址或立即數送到暫存器或儲存單元中。可以仔細分為以下5種:

1 通用資料傳送指令

MOV 傳送

MOVSX 帶符號擴充套件傳送

MOVZX 帶零擴充套件傳送

PUSH 進棧

POP 出棧

PUSHA 所有暫存器進棧

POPA 所有暫存器出棧

XCHG 交換

MOV 傳送指令

;標準:mov dst,src
;執行操作:(dst)<-(src)
;mov指令的機器語言允許有7種模式
mov mem/reg1,mem/reg2
;運算元必須至少有一個是暫存器
mov reg,data
mov ac,mem
mov mem,ac
;意思是隻能通過暫存器和累加器來進行互相互動
mov segreg,mem/reg
;segreg指定段暫存器,但是不能用CS暫存器。因為CS和IP指令只能採用jmp來呼叫,也就是可以用立即數和普通暫存器給段暫存器賦值。

mov mem/reg,segreg
;mem表示立即數,reg為指定暫存器
mov mem/reg,data
;採用儲存器定址方式。


;data為立即數,reg為指定暫存器,segreg為段暫存器,mem表示儲存器也可以說是記憶體。

說明MOV指令可以在CPU內或CPU和儲存器之間傳送字或位元組。可以從暫存器到暫存器,立即數到暫存器,立即數到儲存單元,從儲存單元到暫存器等。

注意事項:

立即數不能之間送到段暫存器,需要將立即數送給reg再用reg送到segreg中。

MOV指令的目的運算元(dst)不允許使用立即數,也不允許使用CS暫存器。

除開源運算元是立即數的情況外,兩個運算元必須有一個是暫存器,不允許用MOV指令在兩個儲存單元直接傳送資料,也不允許在兩個段暫存器間直接傳送資訊。

例子:

;例1
MOV AX,DATA_SEG
MOV DS,AX
;段地址必須通過暫存器傳入,例1採用的是用ax來傳入

;例2
MOV AL,'E'
;將立即數E的ASCII碼送到暫存器AL中

;例3
MOV BX,OFFSET TABLE
;將TABLE的偏移地址送到BX中,如果為陣列就是首地址,OFFSET是一個關鍵字,表示把後面的符號地址傳遞

;例四
MOV AX.Y[BP][SI]
;將EA(有效地址)=BP+SI+Y的儲存內容送給AX暫存器

;例5
MOV EAX,[EBX+ECX*4]
;把有效地址EA=EBX+ECX*4的儲存單元的32位內容送給EAX

MOVSX帶符號擴充套件傳送指令

格式為:MOVSX DST,SRC

執行操作:DST<-符號擴充套件(SRC)

本指令可以有兩種格式:

MOVSX reg1,reg2

MOVSX reg,mem

注意事項:

;指令的運算元可以是8位或16位的暫存器或儲存單元的內容而目的運算元必須是16或32位暫存器,傳送時把源運算元符號擴充套件送入目的暫存器。可以是8位擴充套件到16或32位,也可以是16位符號擴充套件到32位。

同時MOVSX也不影響標誌位的內容。

例子:

;例1:
MOVSX EAX,CL
;把CL暫存器中的8位數,符號擴充套件為32位數送到EAX暫存器中

;例2:
MOVSX EDX,[EDI]
;把DS:EDI指定地址的內容16位數符號擴充套件為32位後送到EDX暫存器中

MOVZX 帶零擴充套件傳送指令

格式為:MOVZX DST,SRC

執行操作:DST<-零擴充套件(SRC)

指令可以有兩種格式:

MOVZX reg1,reg2

MOVZX reg,mem

注意事項

DST和SRC以及對於標誌位的影響都和MOVSX相同,差別只是MOVSX是帶符號做符號擴充套件,而MOVZX的無符號整數是作零擴充套件

MOVZX和MOVSX的標誌是:SRC的操作長度一定要小於目的運算元長度。

例子:
;例1
MOVZX EX,AL
;把AL中暫存器的八位數,零擴充套件為16位送到DS暫存器中。

;例2
MOVZX EAX,DATA
;把DATA單元的16進位制數擴充套件到32位送到EAX暫存器裡

PUSH出棧指令

格式為: PUSH SRC

執行操作為:

16位:SP<-SP-2

((SP)+1,(SP))<-(SRC)

;簡單來說就是偏移地址往上移2個單位,然後寫入一個字給對應的記憶體單元

32位:(ESP)<-(ESP)-4

((ESP)+3,(ESP)+2,(ESP)+1,(ESP))<-(SRC)

;同上,只是把兩個位元組改為了四個

POP進棧指令

格式為:POP DST

執行操作:

16位指令:(DST)<-((SP)+1,(SP))

(SP)<-(SP)+2

其實也就是將sp指向的地址和往下一個地址的兩個位元組的內容整合為字送給16位DST。然後SP段偏移地址再往下移動2個記憶體單元

32位指令:(ESP)<-(ESP)-4

((ESP)+3,(ESP)+2,(ESP)+1,(ESP))<-(SRC)

同上就是擴大了兩倍。

PUSH與POP指令綜合

格式:

PUSH    reg
PUSH mem
PUSH data
PUSH segreg

POP reg
POP mem
POP segreg

;reg表示指定暫存器,mem為記憶體,data為立即數,segreg為段暫存器

進出棧的內容可以為字也可以為雙字。

運算元長度地址長度執行的操作
16 16 sp<-sp+_2 字出棧或者進棧
16 32 ESP<-ESP+-2 字出棧或者進棧
32 16 SP<-SP+-4 雙字出棧或者進棧
32 32 ESP<-ESP+-4雙字出棧或者進棧
PUSH和POP的例子:
PUSH AX;

POP AX;

PUSHA/PUSHAD 所有暫存器進棧指令

格式為:PUSHA

PUSHAD

執行操作:

PUSHA:16位通用暫存器依次進棧,進棧次序為:AX,CX,DX,BX指令執行前的SP,BP,SI,DI。指令執行後(SP)<-(sp)-16依然指向棧頂。

PUSHAD:32位通用暫存器依次進棧,進棧順序為:EAX,ECX,EDX,EBX以及指令執行前的ESP,EBP,ESI和EDI。指令結束後(SP)<-(SP)-32

POPA/POPAD所有暫存器出棧指令

格式為:POPA

POPAD

執行操作:

注意事項

POPA:16位通用暫存器依次出棧,出棧次序為:DI,SI,BP,SP,BX.DX.CX.AX。指令執行後(SP)<-(SP)+16 SP指向棧頂。SP的出棧只是修改了指標使其後面的BX能出棧,而堆疊中原先PUSHA指令存入的SP的原始內容被丟掉,並沒有真正的送到SP暫存器中。

POPAD:32位暫存器依次出棧,次序為EDI,ESI,EBP。。。。同上。(ESP)<-(ESP)+32和POPA一樣。

例子:
PUSHAD

XCHG EAX,EBX

就是EAX和EBX暫存器的內容互換