【汇编】思考汇编中的两个基本问题

1. 若干年前的疑问

几年前还在大学学习汇编时,不管是考试还是课程设计,其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑,编写汇编时,没有十足的把握,都是抱着试一试的心态去完成了课程任务。

工作八年有余,已走在向linux内核进发的路上。在学习linux内核之前,心里存有一些侥幸,认为汇编可以跳过去。别人封装好,只管使用即可,反正自己又不一定写。在学习过程中,涉及到汇编的部分都是大致看一下设计思路。但是逐渐地,跳过的细节越来越多,导致书慢慢的越来越看不懂了。问题积少成多,窟窿越来越大,量变产生了质变。

汇编中的指令还是挺好理解的,就是一些功能函数,我相信大多数人理解起来问题都不大。

我认为汇编中最大的问题在于寄存器和内存的使用。CPU中寄存器的数量有限,引发了两个问题:

  1. 何时该用哪个寄存器
  2. 哪些数据存在寄存器哪些放在内存

这两个问题一直困扰着我,由于工作中用汇编比较少,所以这个问题一直没有得到深入地思考和解决。今天我们就尝试解决这两个汇编问题。

2. 汇编指令与高级语言中函数的相同点和不同点

我们直入主题,汇编指令与高级语言中函数的相同点是:

  • 汇编指令和函数一样,都是为了完成某个操作的功能单元,他们都有输入和输出,说白了,你可以把汇编指令也看成是一种函数。

不同点是:

  • 单个汇编指令不能嵌套调用,可以组合调用;成对搭配的汇编指令,可以嵌套调用,比如CALL和RET。
  • 单个函数可以嵌套调用,也可以组合调用

3. 单个指令的“独占性原理”

寄存器的个数是很有限的,但是指令确有很多很多,寄存器够用吗?

答案是,对单个指令来说,肯定是够用的。因为单个指令不能嵌套,所以我们可以确定,一个指令在被CPU核执行的时候,是“独占”所有它可以操作的寄存器的,因为此刻一个CPU核中不会有其他指令执行。这样一来,我们可以确定,对一条指令来说,寄存器虽然很少,但肯定是足够的。CPU厂家在设计指令时,不会设计使用超额寄存器数量的指令。

单条指令的“独占性原理”,保证了CPU中即使只有有限数量的寄存器,也能正确执行任何单个指令。

4. 多指令协同与优化

从单个指令执行过程看,单个指令执行有“独占性原理”。

从多个指令执行过程看,寄存器还能够用吗?设想一下,如果前一个指令执行后,有很多重要的数据存在于寄存器中保存,而当前的指令又需要独占寄存器,很有可能会把存在于寄存器中重要的数据给“覆盖”、“破坏”了,从而导致重要数据丢失。这种情形下,程序将无法正确执行。出现这种问题的根本原因还是在于寄存器数量有限,如果寄存器数量很多很多,那么只要合理分配和释放,数据就不会被覆盖。

所以,在多指令角度,因为寄存器数量有限,又出现了新的问题。怎么解决这个问题呢?

通过将下一条指令需要的数据留在寄存器中,将下一条指令不需要的数据放到内存中,这个问题迎刃而解。下一条指令需要的数据,其实就是指令的输入参数。前后指令配合的过程,我起个名字,叫“多指令协同”。

其实把下一条指令的输入参数留下,不需要的数据放入内存,是一种简单粗暴的做法。细想之下,如果寄存器数量还有空余,其实可以多留一些数据在寄存器中,给下下条指令,下n条指令传参,这样可以减少内存的访问,提高执行效率。但是这种预留是不确定的,是动态的,是具体的,必须根据具体的指令,使用的参数个数,返回值个数,进行专门优化。这个过程,我称之为“多指令协同优化”。

在编译高级语言的过程中,编译器会在生成汇编语言时,根据编译参数,自动进行优化。在编译程序时,不同的编译优化等级,优化的算法和力度是不同的。如果考虑上CPU的多级缓存,其实优化过程还是很复杂的。这里我们暂时不做深入研究。

5. 汇编编程套路

工作做到最后,都是套路。套路换一个词,就是经验。如何能够把汇编程序写得又快又好,那就需要学习套路。

我们上面说了,当写多条指令的时候需要注意优化寄存器和内存的使用。这个优化太自由了,你可以这么优化,我可以那么优化,自由的东西一定程度上,是没有标准没有把握的东西。我们平时写代码,如何更多的关注于业务呢?这里讲一种方法。

程序都是由一小块一小块功能模块的代码组成的,汇编也是一样。汇编程序是由很多汇编代码段组成的。这里用代码段来讲,而不是用函数来讲,是因为函数也有可能是由几个代码段组成。所以代码段是比函数更小的代码模块。

有了代码段的概念之后,我们可以把“指令独占性原理”,扩展到代码段,变成“汇编代码段独占性”原理。我们可以认为一个代码段执行过程中,独占所有寄存器,代码段执行完成后,可以通过某几个寄存器向接下来的代码段传递参数,剩下的寄存器,默认将成为空闲寄存器,里面的数据可以被覆盖。如果有的寄存器需要延长生命期,可以把寄存器中的数据保存到内存中,从而将寄存器释放出来。

这样,下一个代码段也将独占所有寄存器。这样就不用时刻担心,这个寄存器能不能用,会不会覆盖已有的数据了。

本质上,这是通过控制作用域与生命期,来调整软件架构的方法,这个方法在编程中很常用。

6. 结论

通过一步步推导单指令的“独占性”原理,“多指令协同”,“多指令协同优化”,“汇编编程套路”,可以很好的解答本文开始提出来的疑问。寄存器,内存的使用是有章可循的,大致的原则和方法要心中有数,才能算是对汇编有一定的掌握,编写或者阅读代码时,才能更有信心。

我的学习习惯就是这样,基本的思路逻辑必须先梳理清晰,而不是一头扎进细节里。重要的细节,我在后面的文章中会进行专门探讨。

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

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

相关文章

在Ubuntu 2404上使用最新的PicGo

在转向Ubuntu之后,果断下载了今年最新的Ubuntu2404,但是随之而来的是底层组件的更新,很多以前可以畅快使用的软件,因为需要老版本的组件而不能正确运行,PicGo就是如此 我们从这里打开Release列表 其中Ubuntu可用的只有这个AppIma…

用ue5打开网址链接

需要用到 Launch URL 这个函数 字面意思就是打开填写的链接网页 这里填写的是百度,按下Tab键后就会打开百度的网页

ISP(Image Signal Processor)——HDR技术总结

传统多帧融合技术 拍摄一系列不同曝光时长的图像帧(LDR),然后使用融合算法进行融合成HDR图像。 融合算法可以分为两种 基于照度图估计的融合 基于照度估计需要拟合相机响应函数,详细可以参考如下论文: Recovering H…

C++打造局域网聊天室第七课: Socket编程初步2

文章目录 前言一、Socket的API函数二、服务端建立Socket步骤总结 前言 C打造局域网聊天室第七课: Socket编程初步2 一、Socket的API函数 接着上一课的内容,我们在chartroom.cpp中找到如下位置 插入断点,运行 运行到断点处后,按…

QT(QML语法)-属性(声明,初始化,赋值,属性绑定,属性组,对象列表。属性别名(双向))

目录 1.属性(Property) 2. 对象列表 3. 属性组 4.代码示例 1.属性(Property) 基本属性声明:property 用于声明可绑定的属性。属性绑定:属性可以绑定到对象属性或函数。属性别名:使用 prope…

【razor】echo搭配relay功能分析

echo 要搭配relay 实现作者说relay在linux上跑,可以模拟丢包、延迟目前没看到如何模拟。relay监听9200,有俩作用 echopeer1 发relay,replay 把peer1的包给peer2 ,实现p2p能力。 接收端:采集后发送发给relay的 接收端的地址就是自己,的地址就是本地的9200,因此是让relay接…

Wallpaper壁纸制作学习记录11

操控变形动画介绍 操控变形是使用Wallpaper Engine为角色和某些对象创建复杂动画的一种高级方法。操控变形是一个多步骤过程,要求您有一个单独的图像图层,其中包含要制作动画的角色或对象的剪切图。 操控变形功能相对复杂,您也可以创建仅包含…

黑马程序员Java项目实战《苍穹外卖》Day12

苍穹外卖-day12 课程内容 工作台Apache POI导出运营数据Excel报表 功能实现:工作台、数据导出 工作台效果图: 数据导出效果图: 在数据统计页面点击数据导出:生成Excel报表 1. 工作台 1.1 需求分析和设计 1.1.1 产品原…

windows下Qt5自动编译配置QtMqtt环境

原文链接:windows下Qt5自动编译配置QtMqtt环境(11)-CSDN博客 1、概述 Qt默认是不包含mqtt库的,如果需要使用到mqtt库就只能自己编译配置;网络所有的QtMqtt配置的文章都是编译完成手动复制,非常麻烦&#x…

OpenCV相机标定与3D重建(15)计算给定图像点对应的极线(epipolar lines)函数computeCorrespondEpilines()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 计算给定图像点对应的极线(epipolar lines)。 对于立体图像对中一个图像的点,计算这些点在另一个图像中对应的…

阿里云服务器Linux(centos)系统安装nginx1.20.2

阿里云服务器Linux(centos)系统安装nginx1.20.2 1.安装依赖包 一共要安装4种依赖(基于c语言) yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel2.下载nginx安装包并解压安装包 nginx官网下载:http://nginx.org/en/do…

启智畅想集装箱箱号识别算法,2台相机即可实现较高识别率

启智畅想集装箱箱号识别算法,在货车通道中使用时,一般配备2台相机即可。启智畅想集装箱箱号识别算法,在货车通道中使用时,一般配备2台相机即可实现对集装箱箱号的精准捕捉与识别。这两台相机分别安装在货车通道的后侧和随意侧面&a…

ESP32-S3模组上跑通ES8388(24)

接前一篇文章:ESP32-S3模组上跑通ES8388(23) 二、利用ESP-ADF操作ES8388 2. 详细解析 上一回解析完了es8388_init函数中的第8段代码,本回继续往下解析。为了便于理解和回顾,再次贴出es8388_init函数源码,在components\audio_hal\driver\es8388\es8388.c中,如下: ​ …

【C++】三角形校验和算法优化的深入分析

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述💯老师的解法实现代码解法分析优势缺点 💯我的解法实现代码解法分析优势缺点 💯数学解释:为什么新增条件是冗余的&a…

【C++软件调试技术】dump文件类型与dump文件生成方法详解

目录 1、概述 2、dump文件的分类 2.1、dump按大小分类 2.2、查看dump文件中函数调用堆栈中变量的值 3、调用SetUnhandledExceptionFilter设置异常处理回调函数,然后调用MiniDumpWriteDump生成dump文件 4、使用Google开源库CrashRpt捕获异常,并自动…

持有CSPM证书可以用于评职称吗?

CSPM的诞生背景 CSPM(Certified Strategic Project Manager)即项目管理专业人员能力评价等级证书,是由中国标准化协会(CAS)根据国标《项目管理专业人员能力评价要求》(GB/T 41831-2022)推出的项…

SpringBoot左脚进门之常用注解

类级别注解 SpringBootApplication Configuration //表明这是一个配置类 EnableAutoConfiguration //开启自动配置 ComponentScan() //开启组件扫描1、Configuration: 当一个类被 Configuration 注解…

【时时三省】(NIT计算机考试)Word的使用方法

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 一、软件简介 Microsoft Word,简称Word,是微软公司开发的一款文字处理软件,广泛应用于文档编辑、排版、打印等领域。无论是撰写论文、报告、简历&#xf…

刷题日志【4】

目录 1、猜数字大小 1、猜数字大小 题意有点抽象,我大概讲一下,就是在1——n里面会有一个目标数,我们通过猜数字的方式逼近这个数字,直到解出这个数,之前我们是用二分法求最快达到求解的问题,这道题多了每…

【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】

目录😋 任务描述 相关知识 测试说明 我的通关代码: 测试结果: 任务描述 本关任务:编写一个程序实现环形队列的基本运算。 相关知识 为了完成本关任务,你需要掌握: 初始化队列、销毁队列、判断队列是否为空、进队列…