【汇编】解答若干年前的汇编问题

1. 若干年前的疑问

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

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

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

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

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

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

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

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

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

不同点是:

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

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

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

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

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

4. 多指令协同与优化

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

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

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

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

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

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

底层开发者直接编写汇编程序时,这个"多指令优化"的任务,就由底层开发者来完成了,编程难度更大了,需要考虑的内容更多了。与之对应地,底层开发者获得了加粗样式对程序的更细粒度的控制。

5. 结论

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

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

相关推荐
pigfu3 天前
go 通过汇编学习atomic原子操作原理
汇编·golang·atomic·缓存行·lock指令
小鹿撞出了脑震荡3 天前
汇编学习——iOS开发对arm64汇编的初步了解
汇编·学习·ios
染指11105 天前
21.第二阶段x64游戏实战-分析采集物偏移
汇编·游戏·反游戏外挂·游戏逆向·x64dbg·x64游戏
楠木s7 天前
常见汇编代码及其指定
java·汇编·数据库·安全·网络攻击模型·二进制·栈溢出
suyong_yq10 天前
调试Cortex-M85 MCU启动汇编和链接命令文件 - 解题一则
汇编·arm开发·嵌入式系统
染指111014 天前
18.第二阶段x64游戏实战-MFC列表框
汇编·c++·windows·游戏·游戏逆向·x64dbg
RaLi和夕17 天前
单片机学习笔记9.数码管
汇编·笔记·单片机·嵌入式硬件·学习
yu41062117 天前
GCC 内建函数汇编展开详解
汇编
手打猪大屁21 天前
ARM裸机开发——I.MX6U_汇编LED灯驱动
汇编·arm开发
zhmc22 天前
Keil A51汇编伪指令
汇编