轉移指令
轉移指令(JMP)允許程序員跳過一段程序,跳轉到存儲器的任何位置執行下一條指令。條件轉移則允許程序員根據對數值的測試做出決定。這些數值測試的結果保存在標誌位中,再由條件轉移指令檢測它們。
1.無條件轉移指令
可以分爲短轉移、近轉移、遠轉移。
短轉移-2字節指令,允許在+127和-128字節範圍內轉移
近轉移-3字節指令,允許在+32kb和-32kb範圍內轉移
遠轉移-5字節指令,允許轉移到整個實存儲器系統內的任何內存單元
短轉移和近轉移通常稱爲段內轉移,遠轉移通常稱爲段間轉移。
在80386以上處理器中,如果機器按保護模式運行,有4GB的代碼段,則近轉移是在+2GB和-2GB範圍內;如果按實模式運行,則近轉移是在+32kb和-32kb範圍內。三種指令的機器碼指令格式如下:
上圖主要是以16位爲例,如果是80386及以上處理器,運行在保護模式,位移量就是32位長。以上第二個近轉移指令就是5字節指令,第三個就是7字節指令。
(1)短轉移
短轉移也稱爲相對轉移,因爲它們可以與相關的軟件一起移動到當前代碼段內的任何位置。這是因爲轉移地址不與操作碼一起存儲。替代轉移地址的是操作碼後面的距離,即位移量。短轉移的位移量用一個字節的有符號數表示的距離,這個值的範圍是+127到-128。微處理器執行短轉移時,位移量先被符號擴展,然後加到指令指針(IP/EIP)上,從而得到當前代碼段內的轉移地址。舉例如下:
START:
mov ax, 1
add ax, bx
jmp SHORT NEXT
NEXT:
mov bx, ax
jmp START
(2)近轉移
除了距離較大以外,近轉移類似於短轉移。80386及以上cpu,保護模式下近轉移的位移量位32位長,其代碼段長度達4GB,因此32位的位移量允許近轉移到2GB~-2GB範圍。近轉移同樣也是可重定位的,因此它也是相對轉移。如果代碼段移到存儲器新的位置,轉移指令與操作數之間的距離保持不變,就允許通過簡單的移動代碼段實現重定位。這個特性與可重定位數據段一起使得intel系列處理器完美地用於通用計算機系統。
(3)遠轉移
遠轉移從指令中得到新的段地址和偏移地址,以實現轉移。
as86彙編器中,段間跳轉使用jmpi彙編指令,指令中帶上段和偏移,比如bootsect.s裏面的"jmpi go,INITSEG"。
2.條件轉移指令
8086~80286微處理器的條件轉移指令都是短轉移,這就把條件轉移的範圍限制在相對條件轉移指令位置的+127到-128字節以內。80386以上的微處理器,條件轉移是短轉移或是近轉移,因此允許這些微處理器有條件地轉移到當前代碼段內的任何位置。
3.過程調用
CALL指令跳轉到過程,RET指令從過程返回。執行跳轉時,CALL指令將其後的指令地址壓入堆棧,RET指令從堆棧彈出地址,返回到CALL指令之後的指令運行。
(1)近CALL指令
近CALL指令有3字節長,第1個字節包含操作碼。對於8086~80286微處理器,第2和第3字節包含正負32KB的位移量或距離,這與近轉移指令的格式想同。80386以上的微處理器按保護模式操作時用32位的位移量,允許正負2GB的距離。
(2)遠CALL指令
遠CALL指令的操作碼後面跟隨IP和CS寄存器的值,執行時先將IP和CS內容壓入堆棧。
(3)RET指令
RET指令從堆棧中取出16位數字(近返回)放入IP,或者取出32位數字(遠返回)放入IP和CS中。