匯編第五日
mov ax, offset 標號:取得標號相對於偽代碼後第一條指令地址0的相對偏移量即標號地址
可以發現匯編指令中的idata會直接反映在機器碼中
jmp指令可以修改IP或CS和IP的值,具體格式如下:
①jmp short 標號(段內轉移)
(IP) = (IP)+ 8位位移
8位位移含義是:標號地址減去jmp指令的下一條指令地址即為相對位移地址(可正可負,但是範圍必須在8位數據能表示之內)並不是直接目的地址
8位位移範圍為-128 - 127
例如:
JMP 0008即跳到0BBD:0008位置,但是機器碼中卻沒有反映0008,那是因為將JMP指令放入指令緩沖區中後,IP會自增JMP指令的大小2字節,此時IP為0005,0005跳到0008還需要0003(相對位移),所以機器碼中反映了03
②jmp near ptr 標號(2^16 = 64KB 剛好為一個段最大值所以用於段內轉移)
(IP) = (IP) + 16位位移
16位位移範圍:-2^15 - (2^15)-1
③jmp far ptr 標號(2 ^ 32 > 64KB,段間轉移)
(IP) = (IP) + 32位位移
機器碼中卻反映了目的地址,不為相對位移地址
④jmp reg(段內轉移)
reg為16位:(IP) = (reg)
⑤jmp word ptr 內存單元(段內轉移)
(IP) = (內存單元)
⑥jmp dword ptr 內存單元(段間轉移)
(IP) = (低雙字)
(CS) = (高雙字)
jcxz 標號:
有條件轉移,與cx寄存器內容有關
cx = 0 跳轉到標號位置執行
cx!=0 不跳轉
(IP) = (IP) + 8位位移
loop指令執行過程
1.cx--
2.cx = 0跳轉到標號,反之
(IP) = (IP) + 8位位移
總結:除了jmp far ptr,其余改變IP的都是給出相對位移地址
nop指令:空指令 占1字節
ret指令:
用棧頂數據修改IP值
執行過程:
(IP) = ((SS) * 16 + (SP))
(SP) = (SP) + 2 ;兩步相當於pop ip
retf指令:
用棧頂數據修改IP和CS
執行過程:
(IP) = ((SS) * 16 + (SP))
(SP) = (SP) + 2 ;兩步相當於pop ip
(CS) = ((SS) * 16 + (SP))
(SP) = (SP) + 2 ;兩步相當於pop cs
call指令:
①將IP或CS和IP壓棧即(SP) = (SP) -2; ((SS) * 16 + (SP)) = (IP)
②jmp near ptr 標號(機器碼中表現的是相對位移地址),即(IP) = (IP) + 16位位移
call far ptr 標號:
(SP) = (SP) - 2
((SS) * 16 + (SP)) = (CS);兩步相當於push cs
(SP) = (SP) - 2
((SS) * 16 + (SP)) = (IP);兩步相當於push ip
(CS) = 標號對應的段地址
(IP) = 標號對應的偏移地址;兩步相當於jmp far ptr 標號
call reg(段內轉移):
①push IP
②jmp reg 即(IP) = (reg)
call word ptr 內存單元:
①push IP
②jmp word ptr 內存單元
call dword ptr 內存單元:
①push cs(低16位)
②push ip(高16位)
③jmp dword ptr 內存單元
call和ret配合使用相當於調用一個子程序(相當於高級語言中的調用函數)
mul 16位reg或內存單元:
相乘兩個數要麽都是8位,要麽16位
①mov byte ptr ds:[0]
byte指明數據為8位:
(ax) = (al) * ((ds)*16+0)
②mov word ptr ds:[0]
word指明數據為16位:
(ax) = (ax) * ((ds)*16+0)低16位
(ax) = (ax) * ((ds)*16+0)高16位
對於調用子程序傳參問題:
①參數少可以用寄存器解決
②參數多的話,將參數放入內存空間中,再將其首地址傳過去
通用寄存器都可以化成h和l
Done!!!
匯編第五日