;分析下面的程序,在运行前仔细思考:这个程序可以正确的返回马?运行后在思考:为什么是这样的结果?
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
程序执行流程:
start: mov ax,0开始执行,到mov cs:[di],ax,就把s2:处jmp short s1拷贝到s处,dubug 命令jmp short s1,共占两个字节,恰好占据原本2个nop的内存空间(nop指令占据一个字节)
jmp short s1 在s2处,可以计算一下需要往上编译10个字节(3(jmp short s1)+3*2(mov ax,0)+2(int 21H)),debug可以看到机器码为EBF6,F6是补码,转换一下即10,也即是向上偏移10个字节,这样的话s:处的2个nop的代码修改成EBF6。
程序接着往下运行,跑到s0:jmp short s,这样又s:处,执行EBF6,即往上偏移10字节,计算一下就知道,IP这个时候指向0,跑到codesg段起始位置,即执行mov ax,4c00H;int 21H,也就是返回操作。
;AX=0000 B