這段時間看王爽的匯編看的效率很高,看樣在學習高級語言后再學習asm是速度比較快。其中有講到指令跳轉的地方,我當時想到的就是goto,用匯編來解釋再貼切不過了。我貼上一道習題與講解,加深印象。
---------------------------------
分析下面的程序,在運行前思考:這個程序可以正確返回嗎?
運行后再思考:為什么是這種結果?
通過這個程序加深對相關內容的理解。
assume cs:codesg
codesg 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
codesg ends
end start
-------------------------------------------------------------------------------------------------------------------------------------------------------
程序可以正常返回。
詳細分析:
在此題中較為深入地考察了‘段內直接短轉移’[形如:jmp short 標號]的概念。
我們知道程序中:
mov di,offset s
mov si,offset s2
mov ax,cs:[si]
mov cs:[di],ax
四條指令的作用是將標號s2處的一條指令復制到標號s處。這時我們應該關心所復制的語句"jmp short s1"對程序的影響:我們知道在段內直接短轉移指令所對應的機器碼中,并不包含轉移的目的地址,而包含的是轉移的位移量(如對此概念還不太熟悉,請查看書中第167頁的內容)。也就是說,在源程序的編譯過程中,編譯器遇到‘段內直接短轉移’[形如:jmp short 標號]時就會自動算出其要跳轉的位移量,以便程序在執行‘段內直接短轉移’的指令時就根據位移量進行(向前或向后)跳轉。通過調試中的U命令我們可以看到指令's2:jmp short s1'所對應的機器碼是EBF6,F6h(-10d的補碼)就是跳轉的位移量[此位移量也可由指令's2:jmp short s1'處的偏移地址18h減去指令's2:jmp short s1'后一個字節的偏移地址22h得出]。這時我們就知道了其實復制到標號s處的指令所對應的機器碼就是EBF6(剛好取代兩個nop所對應的機器碼),它的作用就是將當前IP向前移動10個字節。當程序執行標號s0處的指令后,程序便跳到標號s處接著執行標號s處的指令。s處的指令的作用是向前跳10字節,于是便跳到了代碼中的第一條指令,繼續執行后便實現了程序的正常返回。
[注意:此程序不會也不可能執行標號s1處后的指令。]