先看题目:
不得不承认,这道题我是看了别人答案才明白的。
从代码看,应该是这样去分析的,首先程序的入口在start指向的地方,也就是mov ax,0这里,而不是一开始的退出程序的两条语句。
接着两条nop,各占1个字节。
然后mov di,offset s 这句是往di寄存器传递s 的偏移地址;
然后 mov si,offset s2,这句是王寄存器si传递s2的偏移地址
然后mov ax,cs:[si],所以ax保存了执行s2的指针地址。
mov cs:[di] ,ax 然后把s2的执行地址给了cs:[di]这个内存位置。
这里重点提一下s2:jmp short s1,这里从效果看,下一步就是要执行s1 段的代码。而机器指令EBF6,将被拷贝给cs:[di]的内存这里。而EBF6的效果实际上是往回跳10个字节( s1这里mov ax,0 占3个字节,int 21h 占2个字节, mov ax,0占3个字节,这样就是8个字节。而s2的jmp short s1本身占2个字节。这句执行完了,再回去10个字节,刚好就是s1的位置)
所以当EBF6拷贝给cs:[di]后,相当于cs:[di]实际保存了s的执行地址,所以是把EBF6这条机器指令拷贝给了s的nop nop这里。而EBF6的实际意思是往回跳10个字节,而不是字面的jmp short s1的意思,也就是不会跳下去执行s1,而是跳回去10个字节
这样计算下来EBF6本身2个字节,mov ax, 4c00h 3个字节, int 21h 2个字节 , mov ax, 0 3个字节,一共就是10个字节。所以执行完s段的代码后,指针就到了mov ax,4c00h这里。所以程序就正常退出了。