汇编语言过程调用

过程调用的概念

在编写程序时,我们会遇到同样的一段代码的运行效果在很多地方都要使用的情况,而如果每个地方都写一遍难免会造成资源的浪费。为此汇编语言的创作这门就创造了过程调用的概念
汇编语言的过程调用和高级语言的调用函数、和调用方法类似。它的主要作用就是,将一段代码的使用效果引用到此处,以省去重新编写代码的时间。

过程调用的实现

过程调用有一个独立的指令call指令,如call <标识符>。这个指令从字面意思来看,好像是将代码段转移到调用的地方运行,但真实情况却是跳转到调用的代码段。而跳转回来就需要在调用的代码段最后设置ret指令,和高级语言的return相似。

call指令的使用

call的使用主要有四种格式:相对近调用、间接绝对近调用、直接绝对远调用、间接绝对远调用。

  1. 相对近调用,这里的指的是,call指令和其调用目标处在同一个下。
    例如:
section test
	call_add:
		call near proc_1
	
	proc_1:
		....

注意: 这里的near可以省略,call proc_1,编译器一般默认添加near。

当使用相对进调用时,call指令会被编译为0xE8,这是一个3字节的指令,也就是后面的操作数可以有2字节大小,当代码被编译后,标识符会被替换成:(proc_1 - call_add) - 3,也就是call指令的结束到目标指令的开始的长度。

call指令的操作数是一个有符号数也就是它可以调用到距离当前 -32768 ~ 32767的位置。
为负如下,(编译后的计算过程同上)

section test:
	proc_2:
	..... 			;代码没有进行分段

	call_add:
		call proc_2
  1. 间接绝对近调用的意义同上,不同的是代码格式
call 0x7431
call [0x7373]
call cx
call [cx]
call [cx+bi+si+0x02]

相对近调用唯一的不同就是,帮助编译器省掉了计算过程。

以上两中call指令执行时,会首先将ip寄存器中值与操作数相加,然后将ip的值压入栈中,随后,将计算好的值移动到IP中。

  1. 直接绝对远调用,同理,其实就是call指令和调用目标不在同一个段内。代码格式唯一的不同,就是多了一个段地址。
call 0x2000:0x0030

这里的call会被编译成 0x9A,运行时会直接调用到目标地址所指定的位置,而不另外计算。
4. 间接绝对远调用
代码格式

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

注意: 和上面3中格式都不同,这里的far是不能省略的。而且目标地址必须是连续的两个16位数,如proc_1 dd 0x0102, 0x2000,编译器需要通过far关键字来判断,是否读取两个16位数。这里编译器会把低16位作为偏移地址高16位作为段地址,如proc_1所指向的内容,就会在运行时被解释为0x2000:0x0102。

以上两种call指令执行时,会把原来的cs寄存器的内容压入栈中,再把指针寄存器ip的内容压入栈中,然后分别把给出的代码段地址和编译地址移入cs和ip。

返回指令

返回指令ret/retf,和call/call far的使用是一一对应的,一个call必须对应一个ret(写在目标代码的最后位置),同样call far也会对应一个retf。
当然,它们的作用是和call/call far命令相反的,他们的主要作用就是将从栈中弹出的第一个内容作为ip偏移量移动到IP寄存器中,而将第二个内容移动到CS寄存器中。

注意: 这里会有一个问题,如果再目标代码的执行过程中存在有压栈的情况,一定要在最后进行弹栈,否则程序会直接把压入栈中的内容当作返回时代码的地址移入CS:IP中,导致程序出错。

在这里插入图片描述
其实再这里也可以看出一条规律,8086处理器总是将,地址高位作为段基址,低位作为偏移地址,就和段基址和偏移地址的相对位置一样。

补充

使用间接寻址和直接寻址相比更加灵活,我们可以在程序运行通过代码修改目标地址的值,以改变程序跳转的位置。这在我们加载用户程序时非常有用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值