汇编--call和ret指令

CALL和RET指令:

RET指令

  • ret指令:用栈中的数据修改IP,从而实现近转移。使用ret时,相当于pop IP。
  • retf指令:用栈中的数据修改CS和IP,从而实现远转移。相当于 pop ip  pop cs。

CALL指令

  • 根据位移进行的转移:CALL  标号  。   这个指令会将当前IP内的值压入栈,然后再转移到标号处进行指令。相当于 push ip jmp near ptr 标号。
  • 转移目的地址在指令中:CALL far ptr 标号。这个指令会将当前的 CS 和 IP 压入栈中,然后转移到标号处进行指令。相当于push CS  push  IP   jmp far ptr 标号。
  • 转移地址在寄存器中:CALL 16位寄存器 。 这个指令会将当前的 IP 压入栈中 ,然后转移到 IP 为16位寄存器中的值的地方执行指令。相当于 push IP   jmp  16位寄存器。
  • 转移地址在内存中:call word ptr 内存单元地址,call dword ptr 内存单元地址。前者先将IP压入栈中,然后再从内存单元中读取一个字作为偏移地址,然后转到偏移地址所在的地方执行指令,相当于    push ip jmp word ptr 内存单位   。后者先将CS压入栈中,然后再将IP压入栈中。然后从指定内存单元开始读取两个字,高位字节作为CS的值,低位字节作为IP的值。然后转到CS:IP指定的地方执行指令,相当于 push cs  push ip  jmp dword ptr 内存单位。

CALL 和 RET 的配合使用

把这两者配合使用,可以实现类似于c++中的函数调用,在汇编中我们称其为子程序。

我们来分析一下这个程序

 以后我们可以用类似的方法来创建子程序,大体框架为:

子程序标号:子程序内容.....

                      ..........

                      ret

           start: 主程序内容......

                      ..........

                   call  子程序标号           (需要调用子程序的地方)

                   主程序内容......

                   ...........

子程序和主程序的位置关系没有要求。

参数和结果传递的问题:

我们既然创建了子程序,那么就会有参数传递,以及返回结果的问题。我们一般会将参数和结果都放在寄存器中进行传递。

MUL指令:

mul 为乘法指令。

当两个因子都为8位的话(二进制),那么就用8位寄存器,其中一个因子默认在AL中,另一个可以在一个8位寄存器中,也可以在内存单元中,内存单元可以用不同的寻址方式给出。可以是 mul byte ptr  ds:[0]  也可以是  mul  byte ptr [bx]   .

当两个因子中至少有一个为16位的话(二进制),那么就用16位寄存器,其中一个因子默认在AX中,另一个可以在一个16位寄存器中,也可以在内存单元中,内存单元也可以用不同的寻址方式给出。但 byte ptr  要换成  word ptr  。

对于结果:

只要结果没超过16位,那么就放在AX中,超过了,高位放在DX中,低位放在AX中。

这里我把另一个因子放在了bx中。我们可以看到,两个8位的数据,相乘结果大于8位小于16位,放在了AX中。

一个8位的数据和一个16位的数据相乘,结果大于8位,小于16位,放在了AX中。

批量数据传递:

当要传递的数据有很多个时,寄存器会不够用,这时我们可以把参数储存在内存中,用访问内存的形式来传递参数。

比如类似于这样,只要我们把存放参数的那个位置的段地址存入DS中就可以了。

解决除法溢出问题:

取商运算符  int()   如int (28/6)= 4

取余运算符 rem()  如 rem(28/6) =4

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值