匯編入門學習筆記 (八)—— 轉移指令
瘋狂的暑假學習之 匯編入門學習筆記 (八)—— 轉移指令
參考: 《匯編語言》 王爽 第9章
能夠改動ip或者同一時候改動cs和ip的指令統稱為轉移指令。
8086CPU轉移行為分為:
段內轉移:僅僅改動ip
段間轉移:同一時候改動cs和ip
段內轉移按ip改動的範圍可分為:
短轉移:ip改動範圍 -128~127
近轉移:ip改動範圍 -32768~32767
轉移指令分為:
無條件轉移指令。如 jmp
條件轉移指令
循環指令。如 loop
過程。
中斷。
1. offset,nop指令
offset 獲取標號的偏移地址
nop 占用1一個字節
樣例:
assume cs:code code segment start: mov ax,bx mov si,offset start mov di,offset s mov ax,cs:[si] mov cs:[di],ax s: nop nop code ends end start
2. 根據位移進行轉移的jmp指令
(1)jmp short 標號
是段內短轉移。
表示轉移到指定的標號處。且轉移的距離範圍為-128~127
用debug查看此指令時,會看見機器碼。不會保存標號的地址,自會保存轉移的距離
(2)jmp near ptr 標號
是段內近轉移,轉移的距離範圍為-32768~32767。其它與jmp short 標號同樣
2. 轉移地址在寄存器中的jmp指令
jmp 16位 reg
表示 (IP)=(16位 reg)
3.轉移地址在內存中的jmp指令
(1)jmp word ptr 內存單元地址
是段內近轉移。
樣例:轉移到偏移地址為0123H的指令去,即使(IP)= 0123H
mov ax,0123H mov ds:[0],ax jmp word ptr ds:[0]
(2)jmp dword ptr 內存單元地址
是段間轉移
高地址表示轉移的段地址
低地址表示偏移地址
用debug查看機器碼,能夠發現。它是保存了段地址與偏移地址,而不是像段內轉移的指令時保存轉移的距離
樣例:轉移到段地址為0,偏移地址為0123H的指令去。即使得(CS)= 0。(IP)= 0123H
mov ax,0123H mov ds:[0],ax mov word ptr ds:[2],0 jmp dword ptr ds:[0]
4. jcxz 指令
jcxz 指令為條件轉移指令。當cx為0時,轉移(與loop剛剛相反)。
全部條件轉移指令都是短轉移。
樣例:在內存2000H段中查找第一個值位0 的字節。並把它的偏移指定存儲在dx中。
assume cs:code code segment start: mov ax,2000H mov ds,ax mov bx,0 s: mov ch,0 mov cl,[bx] jcxz ok inc bx jmp short s ok: mov dx,bx mov ax,4c00H int 21H code ends end start
5. jmp指令具體分析
向前轉移:jmp s
jmp short s
jmp near ptr s
jmp far ptr s
在像前轉移時。編譯器能夠在讀到標號s後記下AC(地址計算器)的值as。在讀到jmp ...s (上面5種)後記下AC的值aj。編譯器能夠用as-aj計算出disp
(1)假設disp 在 -128~127 內
上面的每一種指令都將轉化為 jmp short s
(2)假設disp 在 -32768~32767 內
對於jmp short s會編譯錯誤
對於jmp s,jmp near ptr s會產生jmp near ptr s所相應的機器碼。
對於jmp far ptr s,所相應的機器碼為:EA 偏移地址 段地址。
先後轉移:
因為不能確定s位置,編譯器先將上面的指令都當做 jmp short s來讀取。記下jmp ..s 指令的位置和AC的值aj。
對於jmp short s 編譯器生成一個EB和一個nop指令
對於jmp near ptr s 編譯器生成一個EB和兩個nop指令
對於jmp far ptr s 編譯器生成一個EB和四個nop指令
當讀到s時,記下AC的值as,計算disp = as - aj
(1)假設disp 在 -128~127 內
指令都為 EB disp 。它們後面的一個nop變成8位的disp 。jmp s(1個)、jmp near ptr s (1個)跟jmp far ptr s (3個) nop指令不變
(2)假設disp 在 -32768~32767 內
對於jmp short s會編譯錯誤
jmp s、jmp near ptr s 後面 兩個nop變成轉移的16位disp。
jmp far ptr s 這填上對應的段地址。偏移地址。
6. 分析一個奇怪的程序
assume cs:code code segment mov ax,4c00h int 21h start: mov ax,0 s: nop nop mov di,offset s mov si,offset s2 mov ax,cs:[si] mov cs:[di],ax s0: jmp short s s1: mov ax,0 int 21h mov ax,0 s2: jmp short s1 nop code ends end start
追後程序會執行s處的
mov ax,4c00h
int 21h
而正常終止。
為什麽?
debug能夠發現,jmp short s1 拷貝到s處後,由原來的jmp 0018H變成 jmp 0000H。
可是本質的機器碼是EBF6沒變就是ip = ip - 10。
匯編入門學習筆記 (八)—— 轉移指令