4

我刚学完 ARM 架构/汇编。如果 SP 寄存器保存下一个要放入数据的内存位置的地址,那么堆的地址是什么?例如,在 C++ 中,如果您在堆上声明一个对象(例如MyObj example = new MyObj();),程序集会是什么样子,从某种意义上说,它知道在哪里example吗?

4

4 回答 4

6

SP 寄存器通常用于跟踪堆栈中的当前位置。这意味着它几乎需要始终指向堆栈。

对于堆则不能这样说。当您需要访问变量时,该变量的地址将存储在指针或应用程序的其他内存引用中。在需要该地址时,可以使用寄存器来进行引用。但是,哪个寄存器的详细信息不仅取决于编译器,而且还可能取决于从同一编译器优化代码后哪个寄存器可用。

于 2012-08-23T00:22:18.540 回答
6

在这种情况下,堆栈是 OS/EABI 提供的较低级别的结构。这就是为什么有一个传统的寄存器。但是,堆是操作系统提供的更高级别的结构。因此,管理和使用它取决于与您的应用程序和操作系统的协议。在汇编术语中,您将使用该堆并通过寄存器取消引用某些地址。

于 2012-08-23T06:33:30.917 回答
2

处理器需要一个用于堆栈指针的特殊寄存器,因为有时(中断或异常)处理器硬件必须直接修改 SP,而不执行任何代码。这对于堆来说不是必需的,因此不需要使用特殊的寄存器来指向堆。在运行时,操作系统决定特定代码块可以在堆上存储东西的位置,并且任何寄存器都可以用来保存该地址。

于 2012-08-23T10:52:11.607 回答
0

在 ARM 的 EABI 中,R13 (SP) 指向完整降序堆栈上最后推送的数据。然而,没有必要一直指出,这样的代码可以是合法的:

考虑到 r0 指向我们的程序可以访问的有效内存位置。

stmfd r0!, {r1-r12, sp, lr}
ldr   r1, [r0]
mov   r2, lr
sub   lr, sp, #4
str   sp, [r4]
add   sp, lr, #4
ldmfd r0!, {r1-r12, sp, pc}

当然这没有意义,但唯一的一点是,如果你可以安全地重新加载 sp、lr 和所有其他被调用者保存的寄存器,你可以随意刮擦它们,同时记住在返回调用者之前恢复它们的值.

另一点,堆栈和堆可能不一定相同,堆是 malloc/free 类型构造的更高级别抽象,而堆栈用于在只有 4 个寄存器不够或用于传递函数参数、数据结构和你可以想象,但堆栈有点难以管理,因为你必须自己跟踪所有数据,而不是仅仅将区域分配给指针,然后在完成后释放它。

通常取决于程序和环境,您可以使用各种技巧和东西进行优化,例如故意破坏一些非临时寄存器并摆脱它,但是您必须在调用者函数中管理它,并且它应该知道寄存器这将在随后的函数调用中被划伤,因此 EABI 可能仅在将控制权转移到另一个程序或接管时才有意义,您可以在 cpu 上做您喜欢的事情,只要确保它像之前一样干净进入了那个地方。

于 2012-08-23T05:55:36.627 回答