楼主说的这个很有趣啊,我刚才也写了个从后面跳向前面的程序
assume cs:code
code segment
s: mov bx,0
mov cx,2
db 65000 dup (0)
jmp near ptr s
mov ax, 4c00H
int 21H
code ends
end s
然后在debug里面调试了一下
在计算disp的时候jmp near ptr s的机器码是E90F02,而这个时候IP指向mov ax, 4c00H,为0FDF1H
又jmp跳转的时候是(IP)=(IP)+disp,所以执行完jmp near ptr s后IP=020FH+0FDF1H,指向了0000H
不论是在计算disp或者是计算IP,编译器均忽略了溢出问题,从而形成了一个跳转"循环"
然而是jmp short的话,在计算disp时,编译器则不会忽略溢出问题
个人猜测是CPU能计算16位数的算术运算,如果计算出的disp超出了-128~127,编译器能正确表示这个disp的值,但jmp short中存放disp的那个字节放不下所以会出错
而在jmp nert ptr中,如果溢出(超出-32768~32767),CPU仍然保留剩下的16位,就是说jmp nert ptr中存放disp的两个直接仍然能保存这个disp,所以没有编译出错
个人的一点假想,欢迎指错和探讨 |