关于跳跃,80386(30多年前的产品)和之后的cpu有一套指令,能够在传统内存1m之内任意跳跃,
没有跳不到的情况,除非代码有误,比如相位问题(phase error).
先看看debug(以cpu的角度)如何处理跳跃.
条件跳跃有2种操作码,比如jz xxx,零标志跳,也就是相同则跳,操作码有
74 (短跳,-80H 至 7FH) 和 0F 84 (长跳-8000H 至 7FFFH, 80386后才有的指令)
无条件跳跃(JMP)也有2种操作码,操作码有
EB (短跳,-80H 至 7FH) 和 E9 (长跳-8000H 至 7FFFH)
跨段跳跃的操作码是EA,之后的4个字节是 [段:偏移]
EA ?? ?? ?? ??
以编译器(MASM)的角度看,若没有伪指令表示哪种CPU,恒以8086为准(没有0F 84等条条件跳跃),也就是条件跳跃只有短跳,没有长跳.除非在代码之前以伪指令 .386标示
代码中若有跳跃,比如
JMP XXXX
若XXXX的址址在这指令之前,编译器自然知道是短跳还是长跳(EB或E9)
若XXXX的址址在这指令之后,编译器不知道(还未扫瞄到)是短跳还是长跳(EB或E9),一律以长跳跳处理,也就是先填上E9 ?? ??,然后直到全部代码扫瞄完毕,发觉XXXX在短跳范围,于是修改了指令,变为EB ?? 90 , 90是填充指令,意即无动作.
但若发觉XXXX不在同段中,比如跨段,则MASM5.1以前的编译器就傻眼了,马上弹出
phase error between passes 的错误.
至于条件跳跃,若没有.386伪指令,一律以短跳处理,超过则出错.