最近我真的很喜欢硬件,一直在研究 CPU 的工作原理。为此,我一直在为组成的 CPU 架构制作汇编程序、反汇编程序和 vCPU。
我学到了很多东西,但有些东西我还是不明白。汇编程序/CPU 如何处理变量?
据我了解,局部变量被分配并存储在堆栈中。但是当 CPU 到达一条需要局部变量值的指令时,它怎么知道它在堆栈中的什么位置呢?汇编器不能在编译时输入地址,对吧?
我不太了解全局变量,除非您在.data
部分(x86 asm)中有它们。当 CPU 到达需要全局变量值的指令时,它如何知道它在内存中的位置?不是每次运行程序都在不同的地方吗?那么汇编器不能给它一个地址,对吧?
我一直在到处寻找答案,但还没有找到。
在 CPU 级别,它们不是变量,它们只是地址、寄存器和其他位置。堆栈不一定是存储它们的地方。
虽然您可能有更高级别的代码说
在机器代码级别,这将被分解为更简单的指令(使用伪代码,而不是真正的 x86 汇编)
变量名称仅供您作为人类使用,CPU 并不关心它们,它们将被汇编器替换为相关的程序内存地址。
据我记得(已经有 20 年了),堆栈并不是用于随机访问的。您可以将值压入堆栈或弹出最后一个项目,但
give me item 9 on the stack
不能说它是如何工作的。充其量是如果您需要堆栈上的第 9 项,那么您必须先将前 8 项从其中弹出,并且可能首先对它们进行任何必要的工作。它是一个队列,而不是随机存储。具体来说,它是一个LIFO(后进先出)队列。
例如,如果您要调用一个函数,您可以将两个项目压入堆栈以作为“变量”传递。接收代码要做的第一件事就是将它们从堆栈中弹出:
(注意将项目推入堆栈的相反顺序)
如何将变量保存为本地和全局变量并不是 CPU 真正关心的事情。这是汇编程序使用的语义和描述性语言的问题,用于决定在用机器代码中的地址替换名称之前将命名变量安排在内存中的哪个位置,以及赋予重用简单的能力的能力本地范围内的名称。
汇编代码可能“接近于裸机”,但仍然存在混淆,例如变量名、局部和全局范围,以及用于使人类更容易处理的其他东西。在 CPU 可以使用它们之前,它们仍然需要一个程序(汇编器)以实际的机器代码重写它们。