英文网站设计哪里好,路由优化大师,文案短句干净治愈,2022年中国电商行业分析报告1. 若干年前的疑问
几年前还在大学学习汇编时#xff0c;不管是考试还是课程设计#xff0c;其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑#xff0c;编写汇编时#xff0c;没有十足的把握#xff0c;都是抱着试一试的心态去完成了课程任务。
工作八年有…1. 若干年前的疑问
几年前还在大学学习汇编时不管是考试还是课程设计其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑编写汇编时没有十足的把握都是抱着试一试的心态去完成了课程任务。
工作八年有余已走在向linux内核进发的路上。在学习linux内核之前心里存有一些侥幸认为汇编可以跳过去。别人封装好只管使用即可反正自己又不一定写。在学习过程中涉及到汇编的部分都是大致看一下设计思路。但是逐渐地跳过的细节越来越多导致书慢慢的越来越看不懂了。问题积少成多窟窿越来越大量变产生了质变。
汇编中的指令还是挺好理解的就是一些功能函数我相信大多数人理解起来问题都不大。
我认为汇编中最大的问题在于寄存器和内存的使用。CPU中寄存器的数量有限引发了两个问题
何时该用哪个寄存器哪些数据存在寄存器哪些放在内存
这两个问题一直困扰着我由于工作中用汇编比较少所以这个问题一直没有得到深入地思考和解决。今天我们就尝试解决这两个汇编问题。
2. 汇编指令与高级语言中函数的相同点和不同点
我们直入主题汇编指令与高级语言中函数的相同点是
汇编指令和函数一样都是为了完成某个操作的功能单元他们都有输入和输出说白了你可以把汇编指令也看成是一种函数。
不同点是
单个汇编指令不能嵌套调用可以组合调用成对搭配的汇编指令可以嵌套调用比如CALL和RET。单个函数可以嵌套调用也可以组合调用
3. 单个指令的“独占性原理”
寄存器的个数是很有限的但是指令确有很多很多寄存器够用吗
答案是对单个指令来说肯定是够用的。因为单个指令不能嵌套所以我们可以确定一个指令在被CPU核执行的时候是“独占”所有它可以操作的寄存器的因为此刻一个CPU核中不会有其他指令执行。这样一来我们可以确定对一条指令来说寄存器虽然很少但肯定是足够的。CPU厂家在设计指令时不会设计使用超额寄存器数量的指令。
单条指令的“独占性原理”保证了CPU中即使只有有限数量的寄存器也能正确执行任何单个指令。
4. 多指令协同与优化
从单个指令执行过程看单个指令执行有“独占性原理”。
从多个指令执行过程看寄存器还能够用吗设想一下如果前一个指令执行后有很多重要的数据存在于寄存器中保存而当前的指令又需要独占寄存器很有可能会把存在于寄存器中重要的数据给“覆盖”、“破坏”了从而导致重要数据丢失。这种情形下程序将无法正确执行。出现这种问题的根本原因还是在于寄存器数量有限如果寄存器数量很多很多那么只要合理分配和释放数据就不会被覆盖。
所以在多指令角度因为寄存器数量有限又出现了新的问题。怎么解决这个问题呢
通过将下一条指令需要的数据留在寄存器中将下一条指令不需要的数据放到内存中这个问题迎刃而解。下一条指令需要的数据其实就是指令的输入参数。前后指令配合的过程我起个名字叫“多指令协同”。
其实把下一条指令的输入参数留下不需要的数据放入内存是一种简单粗暴的做法。细想之下如果寄存器数量还有空余其实可以多留一些数据在寄存器中给下下条指令下n条指令传参这样可以减少内存的访问提高执行效率。但是这种预留是不确定的是动态的是具体的必须根据具体的指令使用的参数个数返回值个数进行专门优化。这个过程我称之为“多指令协同优化”。
在编译高级语言的过程中编译器会在生成汇编语言时根据编译参数自动进行优化。在编译程序时不同的编译优化等级优化的算法和力度是不同的。如果考虑上CPU的多级缓存其实优化过程还是很复杂的。这里我们暂时不做深入研究。
5. 汇编编程套路
工作做到最后都是套路。套路换一个词就是经验。如何能够把汇编程序写得又快又好那就需要学习套路。
我们上面说了当写多条指令的时候需要注意优化寄存器和内存的使用。这个优化太自由了你可以这么优化我可以那么优化自由的东西一定程度上是没有标准没有把握的东西。我们平时写代码如何更多的关注于业务呢这里讲一种方法。
程序都是由一小块一小块功能模块的代码组成的汇编也是一样。汇编程序是由很多汇编代码段组成的。这里用代码段来讲而不是用函数来讲是因为函数也有可能是由几个代码段组成。所以代码段是比函数更小的代码模块。
有了代码段的概念之后我们可以把“指令独占性原理”扩展到代码段变成“汇编代码段独占性原理”。我们可以认为一个代码段执行过程中独占所有寄存器代码段执行完成后可以通过某几个寄存器向接下来的代码段传递参数剩下的寄存器默认将成为空闲寄存器里面的数据可以被覆盖。如果有的寄存器需要延长生命期可以把寄存器中的数据保存到内存中从而将寄存器释放出来。
这样下一个代码段也将独占所有寄存器。这样就不用时刻担心这个寄存器能不能用会不会覆盖已有的数据了。
本质上这是通过控制作用域与生命期来调整软件架构的方法这个方法在编程中很常用。
6. 结论
通过一步步推导“单指令独占性”原理“多指令协同”“多指令协同优化”“汇编编程套路-代码段独占性原理”可以很好的解答本文开始提出来的疑问。寄存器内存的使用是有章可循的大致的原则和方法要心中有数才能算是对汇编有一定的掌握编写或者阅读代码时才能更有信心。
我的学习习惯就是这样基本的思路逻辑必须先梳理清晰而不是一头扎进细节里。重要的细节我在后面的文章中会进行专门探讨。