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暫存器的內容互換