标记堆栈局部变量 (asm)

Labeling stack local variables (asm)

在 ASM 函数中,可以使用堆栈为变量创建局部工作区。

我想知道的是,与使用堆栈指针的显式数字偏移相比,您能否创建标签来引用它们?

例如:有人想 ldr r0, sp+4 但改用符号名称?这样做的正确方法是什么?我无法想象人们会记住一切的数字偏移量。

这真的取决于汇编程序。对于 GNU 工具链(带有 GAS 的 GCC),您可以使用 .S 文件(而不是 .s),gcc 编译器驱动程序将像 C 源文件一样对其进行预处理。所以你可以写

#define VAR sp+4

然后使用

        ldr r0, VAR

请注意,宏的作用域不正确(仅限于当前函数),因此这可能会造成混淆。

I can't imagine people remembering numeric offsets for everything.

所有汇编程序都允许对全局变量使用标签,部分原因是,全局变量通常用于汇编课程作业编程,其中命名的局部变量会在 high-level 语言中使用。

还因为全局变量是使用相对简单的数据声明来分配和初始化的,而使用堆栈存储局部变量需要动态分配、初始化和释放,当然还有相对于堆栈指针的偏移量,而不是通过绝对寻址命名标签。虽然我们在一般编程中倾向于不使用全局变量,但许多 toy/assignment 程序只有一个 main 并且很少或没有函数,因此全局存储在那里实际上是合理的。

许多局部变量和参数被映射到大多数现代机器上的寄存器。有必要识别用于变量、临时变量和参数传递的寄存器,使用某种#define 或等式通常会使这变得更难而不是更容易。许多程序员更喜欢在注释中描述变量及其映射,而不是使用宏或等式。

内存是标量变量映射的最后手段,因为寄存器是首选。这些天,我们在装配中进行了最少的必要量(有时 none)。正如已经提到的,我们可以在编写玩具程序时用全局变量代替局部变量。在这些原因中,使用偏移量并没有你想象的那么严重。


还有一些原因导致给定局部变量的映射在其所在函数的进程中发生变化,因此必须根据情况进行调整(例如,有时由于调用约定的原因,参数会移动到另一个寄存器;其他时候从内存到寄存器以提高性能;如果我们不想要帧指针的开销,那么推送将改变堆栈上已经存在的东西的偏移量)。汇编语言是如此低级,我们通常不想掩盖细节。