什么寄存器指向堆?

时间:2012-08-23 00:17:57

标签: c++ assembly arm heap

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

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分: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上做你喜欢的事情,只要确保它保持干净就像它一样在你进入这个地方之前。