一. 實(shí)驗(yàn)介紹
實(shí)驗(yàn)8 分析一個(gè)奇怪的程序
分析下面的程序,在運(yùn)行前思考:這個(gè)程序可以正確返回嗎?
運(yùn)行后再思考:為什么是這種結(jié)果?
二. 實(shí)驗(yàn)代碼
assume cs:codesg
codesg segment
mov ax,4c00h
int 21h
start:
mov ax,0
s:
nop ;nop 什么也不做占1個(gè)字節(jié)
nop
mov di,offset s ;di 存放s的位移 8H
mov si,offset s2 ;si 存放s2的位移20H
mov ax,cs:[si] ;ax 存放 jmp short s1指令數(shù)據(jù) EBF6(F6 = -9) 實(shí)質(zhì)是往前移9個(gè),
;后面顯示的jmp short s1 會(huì)轉(zhuǎn)化成 jmp (ip)
mov cs:[di],ax ;將s:nop 存ax中的數(shù)據(jù)也就是 EBF6
s0:
jmp short s ;跳轉(zhuǎn)到標(biāo)號(hào)s處執(zhí)行指令 jmp 指令,為數(shù)據(jù) EBF6 往偏移9個(gè)位置剛好是cs:0的位置,所以能正確返回
s1:
mov ax,0
int 21h
mov ax,0
s2:
jmp short s1 ;占2個(gè)字節(jié)
nop
codesg ends
end start
三. 實(shí)驗(yàn)分析
代碼是順序結(jié)構(gòu)進(jìn)行從start標(biāo)號(hào)開始執(zhí)行,一直到s0 都沒有進(jìn)行任何的轉(zhuǎn)移,執(zhí)行到 jmp short s時(shí) ,然后cs:ip又會(huì)指向標(biāo)號(hào)s處的指令,為jmp 指令 數(shù)據(jù)為EBF6 ,其中F6代表要偏移的位置 轉(zhuǎn)為有符號(hào)的8位二進(jìn)制是-10 ,就是往前移10個(gè)字節(jié)(包含本身所占字節(jié)數(shù)) 剛好指向code段開始 翻譯成jmp 指令就是 jmp 0!然后指向 mov ax,4c00,int 21h。所以程序可以正確的返回。
這里最重要的是要理解jmp 指令的本質(zhì),短轉(zhuǎn)移它的二進(jìn)制數(shù)的EBF6,F(xiàn)6代表的是偏移量,然而顯示的jmp指令內(nèi)容是 jmp (ip)!,(ip)會(huì)根據(jù)偏移量自動(dòng)計(jì)算!所以賦值jmp指令內(nèi)容 顯示的匯編指令 是變動(dòng)的,而二進(jìn)制數(shù)卻不是變動(dòng)的。
image
image
總結(jié):
- s 處的指令賦值為:
EBF6,EB開頭的指令代表jmp,F6是-9. -
EBF6代表跳轉(zhuǎn)到前面9字節(jié)處, 執(zhí)行指令
四. 實(shí)驗(yàn)結(jié)果
能正確的結(jié)束程序:
image