call指令和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP,它们经常被共同用来实现子程序的设计

10.1 ret 和 retf

ret指令用栈中的数据,修改IP的内容,从而实现近转移
CPU执行ret指令时,进行两步操作:
1,(IP) = ((ss)*16 + (sp))
2,(sp) = (sp) + 2

相当于:
pop IP

retf指令用栈中的数据,修改CS和IP的内容,从而实现远转移
CPU执行retf指令时,进行四步操作:
1,(IP) = ((ss)*16 + (sp))
2,(sp) = (sp) + 2
3,(CS) = ((ss)*16 + (sp))
4,(sp) = (sp) + 2

相当于:
pop IP
pop CS

下面的程序中,ret指令执行后,(IP) = 0,CS:IP指向代码段的第一条指令

10.2 call指令

CPU执行call指令,进行两步操作:
1,将当前的IP或CS和IP压入栈
2,转移

call指令不能实现短转移,call指令实现转移的方法和jmp指令的原理相同

10.3 依据位移进行转移的call指令

call 标号 (将当前的IP压入栈,转到标号处执行指令)

执行此种格式的call指令时,进行如下操作:
1,(sp) = (sp) -2
((ss)*16 + (sp)) = (IP)
2,(IP) = (IP)+16位位移

相当于进行:
push IP
jmp near ptr 标号

10.4 转移的目的地址在指令中的call指令

call far ptr 标号 实现的是 段间转移

执行此种格式的call指令时,进行如下操作:
1,(sp) = (sp) -2
((ss)*16 + (sp)) = (CS)
(sp) = (sp) -2
((ss)*16 + (sp)) = (IP)

2,(CS) = 标号所在段的段地址
(IP) = 标号所在段中的偏移地址

相当于进行:
push CS
push IP
jmp far ptr 标号

10.5 转移地址在寄存器中的call指令

call 16位reg
功能:
(sp) = (sp) - 2
((ss)*16 + (sp)) = (IP)
(IP) = (16位reg)

相当于进行:
push IP
jmp 16位reg

10.6 转移地址在内存中的call指令

转移地址在内存中的call指令有两种格式:

1,call word ptr 内存单元地址
相当于进行:
push IP
jmp word ptr 内存单元

2,call dword ptr 内存单元地址
相当于进行:
push CS
push IP
jmp dword ptr 内存单元

10.7 call 和 ret 的配合使用

考虑下面程序返回前,bx中的值为多少?

assume cs:codecode segmentstart: mov ax,1mov cx,3call smov bx,axmov ax,4c00hint 21hs:add ax,axloop sretcode ends
end start

分析CPU执行该程序的主要过程:
1,CPU将 call s指令的机器码读入,IP指向了call s后的指令 mov bx,ax,然后CPU执行call s的指令,将当前的IP值(指令mov bx,ax的偏移地址)压栈,并将IP的值改变为标号处的偏移地址
2,CPU从标号s处开始执行指令,loop循环完毕后,(ax)=8
3,CPU将ret指令的机器码读入,IP指向了ret指令后的内存单元,然后CPU执行ret指令,从栈中弹出一个值(即call s先前压入的mov bx,ax指令的偏移地址)送入IP中,则CS:IP指向指令mov bx,ax
4,CPU从mov bx,ax开始执行指令,直到程序完成

10.8 mul 指令

mul是乘法指令,注意两点:
1,两个相乘的数,要么都是8位,要么都是16位,如果是8位,一个默认放在al中,另一个放在8位reg或内存字节单元中,如果是16位,一个默认放在ax中,另一个放在16位reg或内存字单元中

2,结果如果是8位乘法,结果默认放在ax中,如果为16位乘法,结果高位默认放在dx中,低位放在ax中

如:
mul byte ptr ds:[0]
含义:(ax) = (al) * ((ds)*16 + 0)

mul word ptr [bx+si+8]
含义:
(ax) = (ax)*((ds)*16 +(bx)+(si) +8)结果的低16位

(dx) = (ax)*((ds)*16 +(bx)+(si) +8)结果的高16位

10.9 模块化程序设计

可以看到,call 和 ret指令共同支持了汇编语言中的模块化设计,在实际编程中,程序的模块化必不可少,因为现实的问题比较复杂,对现实问题进行分析时,把它转化为相互联系,不同层次的子问题,是必须的解决方法

利用call和ret指令,可以用简捷的方法,实现多个相互关联,功能独立的子程序来解决一个复杂的问题

10.10 参数和结果传递的问题

子程序将结果(返回值)提供给调用者,那么如何存储子程序需要的参数和产生的返回值

如:设计一个子程序,提供N,计算N的3次方
那么考虑:
1,将参数N存储在什么地方?
2,将计算得到的数值存储在什么地方?

显然,可以用寄存器存储,可以将参数放到bx中,将结果放到dx和ax中

用寄存器来存储参数和结果是最常使用的方法,调用者将参数送入参数寄存器,从结果寄存器中取到返回值,子程序从参数寄存器中取到参数,将返回值送入结果寄存器

10.11 批量数据的传递

当子程序需要多个参数时,需要传递多个值,寄存器的数量始终是有限的,不可能简单地用寄存器存放多个需要传递的数据,对于返回值,也有同样的考量

这时,考虑将批量的数据放入到内存中,然后将它们所在的内存空间的首地址放在寄存器中,传递给需要的子程序,对于具有批量数据的返回值,也使用同样的方法

10.12 寄存器冲突的问题

设计一个程序,功能:将一个全是字母,以0结尾的字符串,转化为大写,程序要处理的字符串以0作为结尾符,这个字符串可以如下定义:

db ‘conversation’,0
字符串的内容后面一定要有一个0,标记字符串的结束,子程序可以依次读取每个字符进行检测,如果不是0,就进行大写的转化,如果是0,就结束处理,由于可以通过检测0而知道是否已经处理完字符串,所以子程序可以不需要字符串的长度的作为参数,可以用jcxz来检测0

但上述程序中存在错误,问题在于cx的使用,主程序主要使用cx记录循环次数,可子程序中也使用了cx,在执行子程序时,cx中实际保存的数值被改变,使得主程序的循环出错

解决这个问题的便捷方法是:在子程序的开始将子程序中所有用到的寄存器中的内容都保存起来,在子程序返回前再恢复,可以用栈来保存寄存器中的内容

对capatial段的改进使用栈避免寄存器冲突:

《汇编语言》第十章 call 和 ret 指令相关推荐

  1. 汇编 第十章 call和ret指令

    第十章 call和ret指令 call和ret指令都是转移指令,它们都能修改ip,或同时修改cs和ip 10.1 ret和retf 1.ret指令用栈中的数据,修改ip的内容,从而实现[近转移]CPU ...

  2. 汇编语言(第三版)第十章 CALL 和 RET 指令 笔记

    call 和 ret 都是可以改变 ip 或是 cs 和 ip .经常用来实现子程序设计. 10.1 ret 和 retf ret指令用栈中的数据,修改IP实现近转移 retf指令用栈中的程序,修改c ...

  3. 王爽老师汇编语言第四版第十章CALL和RET指令——小白笔记

    目录 10.1 ret和retf (1)  ret: (2)retf: 10.2 call指令 10.3依据位移进行转移的CALL指令 10.4 转移的目的地址在指令中的CALL指令 10.5转移地址 ...

  4. 王爽 《汇编语言》 读书笔记 十 CALL和RET指令

    第十章 CALL和RET指令 call和ret都是转移指令,它们都修改IP,或同时修改CS和IP,常用于子程序的设计. 10.1 ret 和 retf ret用栈中的数据,修改IP的内容,从而实现近转 ...

  5. 汇编语言笔记10-CALL和RET指令

    ☞模块化程序设计 模块化程序设计 汇编语言通过call和ret指令实现了模块化程序设计.可以实现多个相互联系.功能独立的子程序来解决一个复杂的问题. 子程序的框架 1 assume cs:code 2 ...

  6. 王爽 汇编语言第三版 第10章 call 和 ret 指令 以及 子程序设计

    第10章 call 和 ret 指令 10.1 ret 和 reft 指令 call 和 ret 指令都是转移指令,他们都修改 IP,或同事修改 CS 和 IP .他们经常被共同来实现子程序的设计. ...

  7. 《汇编语言》第10章 call和ret指令

    call和ret指令都是转移指令,经们都修改IP,或同时修改CS和IP.它们经常被共同用来实现子程序的设计.这一章,我们讲解call和ret指令的原理. 10.1 ret和retf ret指令用栈中的 ...

  8. 汇编语言——第10章 CALL和RET指令

    目录 引言 10.1 ret和retf 检测点10.1 10.2 call指令 10.3 依据位移进行转移的call指令 检测点10.2 10.4 转移的目的地址在指令中的call指令 检测点10.3 ...

  9. (十)汇编语言——CALL和RET指令

    (十)汇编语言--CALL和RET指令 文章目录 (十)汇编语言--CALL和RET指令 CALL指令 功能 寄存器 内存 段间转移 返回指令 ret retf 实例 MUL指令 模块化程序设计 寄存 ...

最新文章

  1. 如何查看某个端口被谁占用
  2. Windows系统帮助中心程序的0day漏洞
  3. 最大子数组和Python解法
  4. C++primer 第 3 章 字符串、向量和数组 3.1 命名空间的using声明 3.2标准库类型string
  5. Android 异常问题分析
  6. NOIP练习赛题目6
  7. TensorFlow中查看checkpoint文件中的变量名和对应值
  8. 大数据之-Hadoop3.x_MapReduce_编程规范---大数据之hadoop3.x工作笔记0086
  9. 车机“智能互联”深度评测:第三弹 吉利博越PRO与GKUI 19
  10. virtualbox虚拟机下的cdlinux找不到无线网卡的解决方法
  11. 开源和非开源IM即时通讯源码有什么区别,哪个更好
  12. 需求分析岗的一点总结
  13. java 通过身份证计算年龄性别
  14. 前端vs图片:2 图片深度、图片分类等基本信息
  15. 你对“happen-before原则”的理解可能是错的?
  16. 快消巨头与“饿了么”的数字革命
  17. 微信文章临时链接变永久链接
  18. 用代码在最短时间做成事
  19. android tv tts,android触摸语音事件
  20. Unity初级案例-愤怒的小鸟:四:11解决重复划线和小鸟轮换速度突然变大的问题+12添加小鸟飞出的拖尾效果+13整合场景和解决无法显示划线弹弓的问题

热门文章

  1. 斯塔克尔伯格竞争模型
  2. 不要做一个只会抱怨的人
  3. 牛客网 - [牛客OI周赛7-普及组]救救兔子(二分)
  4. matlab与python区别_python和matlab的区别
  5. ES Module与CommonJS
  6. LeetCode:387.字符串中的第一个唯一字符
  7. handle java
  8. 03-SQLPlus的常用命令和使用
  9. 宽带加速方法!网速提高30%-200%
  10. 联想(Lenovo) 小新M7268W 黑白激光无线WiFi打印多功能一体机 出现:打印机故障:显示扫描单元未找到初始位置 或者 扫描单元马达故障 解决办法