埃尔法哥哥汇编语言跳转指令中跳转地址的计算


x86 指令集包含大量的条件跳转指令 。 它们能比较有符号和无符号整数 , 并根据单个 CPU 标志位的值来执行操作 。 条件跳转指令可以分为四个类型:
基于特定标志位的值跳转
基于两数是否相等 , 或是否等于(E)CX 的值跳转
基于无符号操作数的比较跳转
基于有符号操作数的比较跳转
【埃尔法哥哥汇编语言跳转指令中跳转地址的计算】本文以jmp跳转指令为例 , 说明跳转地址如何计算 。
jmp short 标号(转到标号处执行指令)
这种格式的 jmp 指令实现的是段内短转移 , 它对IP的修改范围为 -128~127 , 也就是说 , 它向前转移时可以最多越过128个字节 , 向后转移可以最多越过127个字节 。
段内转移 , 只修改IP , 比如jmp ax段间转移 , 同时修改CS和IP , 比如jmp 1000:200短转移 , IP取值范围-128-127 ,8位近转移 , IP取值范围-32768-32767 , 16位 。
埃尔法哥哥汇编语言跳转指令中跳转地址的计算
本文插图
图一
上图是清华大学王爽老师编写的汇编语言教材中一个用于说明跳转地址计算的例子 , 这个例子在跳转地址的计算稍微有点复杂 , 下面对这个例子进行说明 。
该程序的运行结果如图2所示 。 从图2可以看出 , 指令mov ax,4c00h;int 21h的作用仅仅是将IP指针指向了它们的下一条指令:start:mov ax,0 。
图二
利用反汇编指令 , 对上述程序得出图3 。 从图中可以看出 , 标号s1的物理地址是076A:0018H , 标号s2的物理地址是076A:0020H , 而指令s2:jmp short s1的指令机器码是EBF6,其中EB的意义是jmp,而F6则代表该指令的跳转距离 。 该距离值计算如下:当CPU将机器码EBF6读入以后 , 其IP指针的内容指向了下一条指令nop , 其物理地址是076A:0022H , 由该地址到标号s1的物理地址076A:0018H的距离是10(十进制) , 由于是向上跳转 , 则其值取负值 , 而十进制-10的补码正是F6 , 其地址计算由0022H+F6H=0018H得出 。
埃尔法哥哥汇编语言跳转指令中跳转地址的计算
本文插图
图三
从图3还可以看出 , 在076A:0008和076A:0009两个存储单元中存储的是两个NOP指令 , 其机器码都是90H , 如图4所示 。
埃尔法哥哥汇编语言跳转指令中跳转地址的计算
本文插图
图四
再对上述程序单步运行 , 当运行到指令mov cs:[di],ax时 , 如图5所示 ,
埃尔法哥哥汇编语言跳转指令中跳转地址的计算
本文插图
图五
埃尔法哥哥汇编语言跳转指令中跳转地址的计算
本文插图
图六
此时076A:0008和076A:0009两个存储单元中存储的内容变成了EBF6,如图6所示 。 继续单步运行指令s0:jmp short s , 此时CS和IP变为076A:0008H , 然后CPU读入机器码EBF6,接着IP变为0010H , 再按照前述的地址跳转计算方法 , 得出当机器码EBF6执行完成后 , IP将变为0000H,因此接着将再次执行指令mov ax,4c00h;int 21h , 当该指令再次执行完成以后 , 整个程序将跳出结束 , 如图7所示 。 由以上过程也可以看出 , 当指令mov ax,4c00h;int 21h放在程序开始的地方 , 其作用仅仅是将IP指针指向这条指令的下一条指令地址 , 而当这条指令在程序执行过程中被执行的时候 , 却将使得IP指针跳出整个程序 。
埃尔法哥哥汇编语言跳转指令中跳转地址的计算
本文插图
图七