汇编语言入门:CALL和RET的配合使用(一)

本系列教程完全参照王爽《汇编语言(第三版)》,这本书对call、ret指令做了相当一部分的讲解,其重要性可见一斑


从栈的角度分析call和ret

分析以下代码

assume cs:code

stack segment           
    db 8 dup (0)        1000:0008 00 00 00 00 00 00 00 00
    db 8 dup (0)        1000:0000 00 00 00 00 00 00 00 00
stack ends

code segment
    start:mov ax,stack        1001:0000 B8 00 10
          mov ss,ax           1001:0003 8E 00
          mov sp,16           1001:0005 BC 10 00
          mov ax,1000         1001:0008 B8 E8 03
          call s              1001:000B E8 05 00
          mov ax,4c00h        1001:000E B8 00 4C
          int 21h             1001:0013 03 C0
        s:add ax,ax           1001:0013 03 C0
          ret                 1001:0015 C3
code ends
end start

分析(从start代码段开始看)

1. 初始化栈CS、IP指针(dup表示重复,共16个0),让SS=1000,SP=16

2. 让(ax) = 1000

前三条指令执行后,如图所示

这里写图片描述

3. 调用子程序,push下一行的首地址(push 000E,call默认进行near转移)

4. 进入子程序s(CPU从cs:0013H开始执行)

5. ret指令读入,IP首先自增1(这个不重要),CPU接着执行C3处的代码,相当于pop IP,执行后,栈中的情况为

6. CPU回到cs:000EH处继续执行

扫描二维码关注公众号,回复: 1619906 查看本文章

这里写图片描述


call和ret的配合使用,与高级语言的关系

call指令

push ip
jmp 标号      ; 默认near转移

ret指令(near转移)

pop ip

retf指令(far转移)

pop ip
pop cs

高级语言的程序返回

void foo()
{
    printf("foo");
    return;
}

高级语言的return语句通常相当于汇编语言的retf(远转移)


mul指令

mul指令用来做乘法,它只能进行8位/8位或16位/16位的乘法

如果是8位/16位乘法,要先将8位用16位数据进行存储(高位补0)

根据参与乘法的两个数的位数,结果保存在ax或ax和dx中

猜你喜欢

转载自blog.csdn.net/abc_12366/article/details/80304889
今日推荐