汇编 --- 过程调用 和 过程返回

读书笔记《x86 从实模式到保护模式》

16位相对近调用

特点

被调用的目标过程位于当前代码段内,而非另一个不同的代码段,所以只需要提供偏移地址

模式

call near proc_1

near指代这个调用是近调用,这个关键字是可缺省的,不指定则默认为near的近调用

proc_1来自程序中的某个标号,编译阶段proc_1被替换为其所在的汇编地址

解释

这个指令是三字节的指令:

操作码占一个字节,0XE8

操作数占两个字节,为什么?因为一个段的大小为2^16(还记得段要放在16字节对齐的地方),近调用的目标过程只会在这个段内,所以其操作数最大只有两个字节

编译阶段计算这个操作数的过程:proc_1所在的汇编地址减去这条call指令所在的汇编地址再减去3  计算出的值会替换掉proc_1  从而机器码变为:0xE8 计算出的值

addr(proc1) - addr(instruction) - 3 = val(operator)

当程序执行过程中CS:IP指向了这条指令,发现操作码为0xE8,处理器就知道这是个过程调用的命令,随即将后面的值拿过来加上当前IP的内容,再加上3就得到了一个新的偏移地址

这个地址当然要放入IP让CS:IP能够跳转过去的,但这个动作之前会把IP当前值保存到栈中,最后采用计算出的值替换IP中的内容。

由于计算过程中是两个汇编地址的相减,如果proc_1在这条call指令之前,那么计算出的操作数就是正的,反之则是负数。所以这个操作数是有符号数,其值当然也就是不是0~2^16-1

而是-(2^16)/2 ~ (2^16)/2

16位间接绝对近调用

特点

这种调用过程和16位相对近调用相似,区别在于相对和绝对。相对是计算偏移值,而绝对则是给出了过程所在的绝对汇编地址。过程同样是限制在本段中,不跨段调用。

模式

call cx
call [0x3000]
call [bx]
call [bx+si+0x02]

解释

由于绝对调用需要给出绝对地址,CS段寄存器不变,都是在一个段,IP是要替换的,现将IP寄存器压栈,用操作数替换IP,随后跳转到操作数所在的汇编地址上运行。

间接体现在操作数的获取必须要先访问地址如上面的0x3000取出地址上的值,也就是偏移地址,才能进行跳转

16位直接远调用

特点

和16位间接绝对近调用相似,直接一词说明可以直接给出跳转地址了,远调用说明不仅IP需要提供,CS也需要。

模式

call 0x2000:0x1000

16位间接绝对远调用

特点

间接:跳转地址是间接给出的

绝对:不需要计算偏移

远:可以跨段调用

模式

call far [0x2000]
call far [proc_1]
call far [bx]
call far [bx+si]

....


proc_1 dw 0x0102,0x2000

解释

间接远调用必须加上far关键字

指令中仅仅需要给出保存过程所在绝对汇编地址的标识所在的偏移地址

proc_1所在的汇编地址上保存了两个字:0x0102和0x2000   这就是要跳转的proc_1过程所在的汇编地址

过程返回

过程返回只有两种:

ret和retf

ret负责过程结束将之前压入栈的IP值恢复到IP寄存器

retf要稍微复杂一点,得恢复CS和IP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值