《汇编语言》- 读书笔记 - 第10章-CALL 和 RET 指令

news2024/11/25 12:59:17

《汇编语言》- 读书笔记 - 第10章-CALL 和 RET 指令

  • 10.1 ret 和 retf
    • 检测点 10.1
  • 10.2 call 指令
  • 10.3 依据位移进行转移的 call 指令
    • 检测点 10.2
  • 10.4 转移的目的地址在指令中的 call 指令
    • 检测点 10.3
  • 10.5 转移地址在寄存器中的 call 指令
  • 10.6 转移地址在内存中的 call 指令
    • 检测点 10.5
  • 10.7 call 和 ret 的配合使用
    • 问题 10.1
  • 10.8 mul 指令
    • 例1. 计算 100*10
    • 例2. 计算 100*10000
  • 10.9 模块化程序设计
  • 10.10 参数和结果传递的问题
  • 10.11 批量数据的传递
  • 10.12 寄存器冲突的问题
    • 问题举例:
    • 解决思路:
    • 子程序的标准框架
      • 改进后的子程序 capital
  • 实验 10 编写子程序

callret 指令都是转移指令,都有修改 IPCS:IP两个版本。
callret 指令共同支撑了汇编语言中的 模块化设计实现。
call 指令用于 调用子程序,它将 返回地址压入 堆栈并跳转至 子程序入口地址。
ret 指令在 子程序执行 完毕后从 堆栈中弹出 返回地址,并跳转回 主程序调用点继续执行。

10.1 ret 和 retf

指令修改CS修改IP行为用途
ret
(Return from Procedure)
POP IP:将栈顶的值弹出,并送进IP从子程序返回。
retf
(Return from Procedure Far)
POP IP将栈顶的值弹出,送进IP
POP CS将从栈中弹出一个值,送进CS
从远过程(far subroutine)返回

检测点 10.1

《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 10.1

10.2 call 指令

CPU 执行 call 指令时,进行两步操作:

  1. 将当前的 IPCSIP 压入栈中;
  2. 转移。(与 jmp 唯一的不同在于没有短转移 : jmp short 标号 )
命令说明修改的
寄存器
例子(假设有标号叫 label
call 标号位移跳转,实现段内转移。位移范围在:-32768 ~ 32767
将当前IP压栈后,转到标号处执行指令。相当于:
1. push IP
2.jmp near ptr 标号
IPcall label
call far ptr 标号目标地址,实现段间转移。相当于:
1. push CS
2. push IP
3.jmp far ptr 标号
CS:IPcall far ptr label
call 16位寄存器转移地址在寄存器中,相当于:
1. push IP
2.jmp 16位寄存器
IPcall ax
call word ptr [内存]转移地址在内存中,实现段内转移。相当于:
1. push IP
2.jmp word ptr 内存单元地址
IPcall word ptr ds:[0]
call dword ptr [内存]转移地址在内存中,实现段间转移。相当于:
1. push CS
2. push IP
3.jmp dword ptr 内存单元地址
IPcall dword ptr ds:[0]

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

检测点 10.2

《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 10.2

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

检测点 10.3

《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 10.3

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

## 检测点 10.4
《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 10.4

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

检测点 10.5

《汇编语言》- 读书笔记 - 各章检测点归档 - 检测点 10.5

10.7 call 和 ret 的配合使用

问题 10.1

下面程序返回前,bx 中的值是多少?

assume cs:code 
code segment
start:	mov ax,1
		mov cx,3
		call s
		mov bx,ax		;(bx)=?
		mov ax,4c00h
		int 21h
s:		add ax,ax
		loop s
		ret
code ends
end start
  1. call s 会将当前 IP 存入栈中,跳到 s 处执行。
  2. s 标号这里是一个 loop 循环 cx 初始为 3 所以会循环 3 次。
    2.1. 第一次 add ax, ax, ax = 1+1 = 2;
    2.2. 第二次 add ax, ax, ax = 2+2 = 4;
    2.3. 第三次 add ax, ax, ax = 4+4 = 8;
  3. loop 循环结束后 ret 返回 call s 处,继续执行它下面的指令。此时 ax = 8
    sret这段实现的是计算2n 次方,ncx 提供。
  4. 所以 mov bx, ax 的结果是 bx = 8
  5. 下一句 mov ax,4c00h 退出程序,最终程序返回前 bx 中的值是 8

通过对问题 10.1的探讨,引出:利用 callret 来实现子程序的机制。
子程序的框架如下:

标号:
	指令
	ret

具有子程序的源程序的框架如下:
在这里插入图片描述

10.8 mul 指令

mul 是乘法指令。两个相乘的数,要么都是8位,要么都是 16 位

  1. 乘数:可以是816位。
    1.1. 但两个乘数必须都是 8位,或都是16位。(不能一8位,一个16位)
    1.2. 如果是8位乘法:一个乘数默认在 AL 中,另一个在8位寄存器内存【字节】单元中。
    1.3. 如果是16位乘法:一个乘数默认在 AX 中,另一个在16位寄存器内存【字】单元中。

  2. 结果
    2.1. 8位乘法:结果在AX
    2.2. 16位乘法:结果高16位DX低16位AX

乘法位数乘数A乘数B结果例子
8位乘法ALah | bl | bh | cl
| ch | dl | dh | [字节单元]
AXmul bl
mul byte ptr ds:[0]
16位乘法AXbx | cx | dx | [字单元]DX AXmul bx
mul word ptr [bx+si+8]

例1. 计算 100*10

assume cs:code 
code segment
start:	
	mov al,100
	mov bl,10
	mul bl
code ends
end start

在这里插入图片描述

parseInt('03E8', 16); // 1000

例2. 计算 100*10000

assume cs:code 
code segment
start:	
	mov ax,100
	mov bx,10000
	mul bx
code ends
end start

在这里插入图片描述

parseInt('F4240', 16); // 1000_000

10.9 模块化程序设计

  1. 模块化设计在汇编语言中至关重要,通过拆解复杂问题为相互关联的子问题
  2. callret 指令支持模块化编程,分别用于调用返回子程序。
  3. 子程序利用这两指令实现功能独立逻辑分离,便于解决复杂问题。

总之,callret 提供了实现子程序的基础,以解决复杂的编程问题。什么提高代码可读性、可维护性和复用性,布啦布啦布啦。。。

10.10 参数和结果传递的问题

  1. 在设计函数经常要考虑的就是怎么传参、怎么返回值。
    1.2. 优先使用寄存器,比较方便。寄存器不够用,就使用内存。
  2. 注释要写清楚。起码以后自己要能看懂(不要高估和曾经那个自己之间的默契)

编程,计算 data 段中第一组数据的3次方,结果保存在后面一组 dword 单元中。

assume cs:code 
data segment
	dw 1,2,3,4,5,6,7,8
	dd 0,0,0,0,0,0,0,0
data ends

code segment
start:	mov ax,data		; 设置数据段
		mov ds,ax
		mov si,0		;ds:si 指向第一组 word 单元
		mov di,16		;ds:di 指向第二组 dword 单元
		
		mov cx,8		; 设置循环次数 8
	s:	mov bx,[si]		; 主程序,读取数据到 bx ("用 bx 传参")
		call cube
		mov [di],ax		; 先存低16"主程序拿到子程序放在 ax 中的返回值"
		mov [di].2,dx	; 再存高16"主程序拿到子程序放在 dx 中的返回值"
		add si,2		;ds:si 指向下一个 word 单元
		add di,4		;ds:di 指向下一个 dword 单元
		loop s
		
		mov ax,4c00h
		int 21h
						; cube 子程序:计算 n 的 3 次方
 cube:	mov ax,bx		; 子程序从("bx 读取传参")
		mul bx
		mul bx
		ret				; 子程序返回 "(返回值)""ax,dx" 中
code ends
end start

在这里插入图片描述

计算 3 次方的数12345678
内存中结果
低位在前,高位在后
(高16位都是0忽略)
01 0008 001B 0040 007D 00D8 0057 0100 02
调整一下顺序00010008001B0040007D00D8015702 00
转成10进制182764125216343512

10.11 批量数据的传递

数据大了就需要用内存传参返回了。
寄存器用来传递内存地址。

assume cs:code 
data segment
	db 'conversation'
data ends

code segment
start:	mov ax,data		; 设置数据段
		mov ds,ax
		mov si,0		; ds:si 指向字符串(批量数据)所在空间的首地址
		mov cx,12		; cx存放字符串的长度
		
		call capital	; 调用子程序
		mov ax,4c00h
		int 21h
		
		; 子程序:转大写
capital:and byte ptr [si],11011111b ; 转为大写字符
		inc si
		loop capital				; 循环处理字符
		ret
code ends
end start

在这里插入图片描述

10.12 寄存器冲突的问题

本节用一个子程序 举例,在主程序子程序使用了同样的寄存器,那么将产生冲突。

问题举例:

  1. 首先:主程序在 CX 中保存了循环次数。
  2. 然后:子程序中的循环计数也用到了CX
  3. 结果:当从子程序返回主程序时,主程序的循环计数已经丢失。程序无法按预期执行。

解决思路:

  1. 子程序具体业务代码开始前,把会用到的寄存器保存到中。
  2. 子程序返回前出栈还原寄存器
  3. 注意入栈出栈时的顺序。(后入的先出)

子程序的标准框架

最终得出编写子程序的标准框架如下:

子程序开始:	子程序中使用的寄存器入栈
			子程序内容
			子程序中使用的寄存器出栈
			返回(ret、retf)

改进后的子程序 capital

capital:
		push cx
		push si
 change:
		mov cl,[si]
		mov ch,0
		jcxz ok
		and byte ptr [si],11011111b
		inc si
		jmp short change
	 ok:
		pop si
		pop cx
		ret

关于大小写的相关知识,详见:第7章 7.4 大小写转换的问题

实验 10 编写子程序

《汇编语言》- 读书笔记 - 实验 10 编写子程序

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1457170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW高速信号测量与存储

LabVIEW高速信号测量与存储 介绍了LabVIEW开发的高速信号测量与存储系统,解决实验研究中信号捕获的速度和准确性问题。通过高效的数据处理和存储解决方案,本系统为用户提供了一种快速、可靠的信号测量方法。 项目背景 在科学研究和工业应用中&#xf…

session和cookie理解

目录 1、理解无状态 2、Session和Cookie理论 3、使用session存储数据 前言,理解session与cookie对于我们做web测试、接口测试、性能测试都是非常有帮助的。 cookie是一些数据信息,存储在浏览器端。 session是存储于服务器端的特殊对象,服务器…

Java并发基础:CompletableFuture全面解析

内容概要 CompletableFuture类使得并发任务的处理变得简单而高效,通过简洁的API,开发者能轻松创建、组合和链式调用异步操作,无需关心底层线程管理,这不仅提升了程序的响应速度,还优化了资源利用率,让复杂…

【Redis】 如何保证数据不丢失?

目录 1.Redis 持久化 1.1 RDB 持久化 1.2 AOF 持久化 1.3 混合持久化 2.Redis 集群 2.1 主从同步 2.2 哨兵模式 2.3 Redis Cluster 小结 1.Redis 持久化 持久化是指将数据从内存中存储到持久化存储介质中(如硬盘)的过程,以便在程序重…

C++之Easyx——图形库的基本准备工作

什么是Easyx? EasyX Graphics Library 是针对 Visual C 的免费绘图库,支持 VC6.0 ~ VC2022,简单易用,学习成本极低,应用领域广泛。目前已有许多大学将 EasyX 应用在教学当中。 它比Red PandaDev C上的图形库功能要强…

好用的UI自动化测试平台推荐

随着软件行业的不断发展,建立一个完善的自动化测试体系变得至关重要。目前,自动化测试主要涵盖接口自动化测试和UI自动化测试两个主要领域。就目前而言,企业在UI自动化测试方面的覆盖率仍然相对较低。 接口自动化测试可以模拟和执行应用程序…

怎么清理mac系统缓存系统垃圾文件 ?怎么清理mac系统DNS缓存

很多使用苹果电脑的用户都喜欢在同时运行多个软件,不过这样会导致在运行一些大型软件的时候出现不必要的卡顿现象,这时候我们就可以去清理下内存,不过很多人可能并不知道正确的清内存方式,下面就和小编一起来看看吧。 mac系统是一…

虚拟机--pc端和macOS端互通

windows开启虚拟化 要在Windows系统中开启虚拟化,您可以按照以下步骤操作: 准备工作: 确保您的计算机CPU支持虚拟化技术。在BIOS中开启相应的虚拟化支持。 开启虚拟化: 打开控制面板,点击程序或功能项&am…

初识KMP算法

目录 1.KMP算法的介绍 2.next数组 3.总结 1.KMP算法的介绍 首先我们会疑惑,什么是KMP算法?这个算法是用来干什么的? KMP(Knuth-Morris-Pratt)算法是一种用于字符串匹配的经典算法,它的目标是在一个主文本…

Allegro172版本如何用自带功能改变过孔网络属性操作指导

Allegro172版本如何用自带功能改变过孔网络属性操作指导 在用Allegro做PCB设计的时候,时常会需要将过孔的网络进行变更,可以将原来的过孔删除,再重新打一个,这种方法难免会繁琐一些。 当然我们可以借助skill工具来完成更换过孔网络的更改,除此之外,Allegro自带的功能完成…

Excel常用快捷键(持续更新)

引言 excel是我们办公中经常使用的工具,古语言“工欲善其事必先利其器”。excel是一个好的工具,但是工具里面有很多常用的快捷键,若我们熟记这些快捷键,便可以提高我们的工作效率。本文为持续更新,望有助于搬砖。 1、C…

简单的线程池——从单线程到多线程——从零基础到零基础(站长素材)

多进程(Process)-读取到数据,要用cpu来运行大量的次数和时间(多线程)(cpu密集型)——multiprocessing 多线程(Thread)-IO多的,同时运行任务数目不多&#xf…

stm32学习笔记-STLINK使用

stm32学习笔记-STLINK使用 使用ST-LINK调试程序进度表格 使用ST-LINK调试程序 说明 组成 总结 记录使用STLINK进行项目的烧写和调试,旨在高效的进行代码调试学习工具包括笔记本、keil5MDK、stm32f030c8t6电表主机、STLINK V2、导线、电表代码总的来说&#xff0…

Kernel 地图

前言 在 Linux Kernel 中,根据 Makefile 和 Kconfig,可以快速地了解一个小的内核子系统。所以我将这两个文件称之为 Kernel 地图。 Kernel 地图 基本上,Linux 内核中,每一个目录下面都有一个 Makefile 和一个 Kconfig 文件。这…

ubuntu 之 zeitgeist-fts 占用内存

座右铭:怎么简单怎么来,以实现功能为主。 欢迎大家关注公众号与我交流 sudo chmod -x /usr/bin/zeitgeist-daemonsudo chmod -x /usr/bin/zeitgeist-datahublocate zeitgeist-ftssudo chmod -x /usr/lib/x86_64-linux-gnu/zeitgeist-fts # 使用 locate z…

星纪魅族宣布 All in AI;欧盟将首次对苹果处以罚款丨 RTE 开发者日报 Vol.146

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE (Real Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

125.乐理基础-五线谱-大六度、小六度

内容参考于:三分钟音乐社 上一个内容:124.乐理基础-五线谱-大三度、小三度-CSDN博客 上一个内容里练习的答案: 然后g1到降e2是一个六度,g1到e2也是一个六度,但是它们俩距离是不一样的 然后在六度前面加上大或小&…

盲盒小程序开发:创新科技与消费者心理的完美结合

随着科技的飞速发展,小程序已经深入到我们生活的方方面面。而在众多小程序中,盲盒小程序以其独特的魅力,吸引了大量消费者的关注。本文将探讨盲盒小程序的发展背景、市场需求、开发流程以及未来趋势,以期为相关行业的从业者提供一…

mybatis-plus(五)-mybatis处理多数据源

mybatisplus多数据源 引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>2.5.6</version> </dependency>配置文件 创建一个数据用户&#x…

【XR806开发板试用】+移植rosserial到XR806

1 XR806简介 板子来源于极术社区的试用&#xff0c;XR806的在线网址 其主要参数&#xff1a; 主控XR806AF2LDDRSIP 288KB SRAM存储SIP 160KB Code ROM. SIP 16Mbit Flash.天线板载WiFi/BT双天线&#xff0c;可共存按键reboot按键 1&#xff0c;功能按键 1灯红色电源指示灯 1…