轉移指令有如下:
1.無條件轉移指令(如:jmp)
2.條件轉移指令
3.迴圈指令(如:loop)
4.過程
5.中斷
運算子offset(取得標號的偏移地址)
jmp指令 --> 可以只修改IP ,也可以同時修改 CS 和 IP(實際是根據位移來轉移的指令)
怎麼計算位移
位移:該 jmp 要跳轉到的標號內的第一個指令的偏移地址 減去(-)jmp 指令下一指令的偏移地址
機器碼的位元組數一般為 2 ~ 3 個位元組 --> 機器本身的位元組(1個位元組) + 值的位元組(暫存器的位元組為2,al,ah等的位元組為1)(值分為1位元組值,如:21h --> (轉化成彙編裡的值)21 等,2位元組值,如:2000h --> (轉化成彙編裡的值)0020),用來計算當前指令下一指令的偏移地址
jmp後的偏移地址為(即IP的值): jmp 下一條指令的偏移地址 + 位移(可能為正也可能為負)
https://fishc.com.cn/thread-27458-1-1.html
(借鑑的網站)
這裡注意,此位移的計算只能適用於原有的語句,經過複製後得到的語句位移不變,即複製過後的語句的執行後的 ip == 該語句之下的一條語句 + 原有語句計算出來的位移
如:
首先我們能計算出 jmp short s 的 位移量 為 0008-0018 = -10(注意這裡是十六進位制的-10 --> (二進位制)-16)
則執行 jmp short s 後ip 應該 == 0018 + (-10) == 0008 --> 恰好對應 s 的偏移地址
其次我們也能計算處 jmp short s1 的 位移量 為 0018-0022 = -10(注意這裡是十六進位制的-10 --> (二進位制)-16)
由於 s 中的 jmp short s1 是複製過去的所以位移量不變 == 0018-0022 = -10 所以當執行 s 中的 jmp short s1 時
ip == 000A + (-10) = 0
可能的問題:
(1)s 中不是有兩個 nop(nop指,這是一條空語句) 嗎?為什麼複製過後一個都沒了呢? --> 這個跟機器碼所佔的位元組有關,nop 所佔的位元組為 1,兩個恰好是2位元組,而jmp short s1 這條指令所佔的位元組為2位元組,剛好覆蓋了兩個nop
(2)為什麼使用000A來計算而不是0009來計算呢?--> 與問題1有關,複製後的程式碼應該如圖:
可以清楚的看到0008和0009這兩偏移地址被用來存放jmp short s1 這一語句了
需要:
轉移的目的地址
轉移的距離(段間轉移,段內短轉移,段內近轉移)
jmp short 標號(轉到標號處執行指令)
此種格式的jmp指令實現的是段內短轉移
對IP的修改範圍為 -128 ~ 127
即向前轉移最多可以越過128個位元組
向後轉移最多可以越過127個位元組
jmp near ptr 標號
該實現的是段內近轉移
對IP的修改範圍為 -32769 ~ 32767
即向前轉移最多可以越過32769個位元組
向後轉移最多可以越過32767個位元組
以上兩種轉移都是基於當前的IP的轉移
jmp far ptr 標號
實現的是段間轉移 --> 遠轉移
far ptr 指明瞭指令用標號的段地址和偏移地址,修改CS和IP
jmp 16為暫存器
功能:IP = (16位暫存器所存的值)
(1)jmp word ptr 記憶體單元地址(段內轉移)
該記憶體單元地址處開始存放著一個字(資料),該字(資料)就是轉移的目的偏移地址
(2)jmp dword ptr 記憶體單元地址(段間轉移)
該記憶體單元地址處開始存放著一個兩個字(資料),高地址處的字(資料)是轉移的目的的段地址,低地址處的字(資料)是轉移的目的的偏移地址(第一個字(資料)為低地址,第二個字(資料)為高地址)
所有的有條件轉移指令都是段轉移,對IP的修改範圍都為 -128 ~ 127
jcxz指令(有條件轉移指令)
格式:jcxz 標號
如果 cx = 0 那麼轉移到標號處執行
反之,則執行該語句的下一條指令,即跳過jcxz指令
loop指令(有條件轉移指令)
格式 loop 標號
如果 cx != 0 那麼轉移到標號處執行
反之,則執行該語句的下一條指令,即跳過jcxz指令