C++ 什么寄存器指向堆?

C++ 什么寄存器指向堆?,c++,assembly,arm,heap,C++,Assembly,Arm,Heap,我刚刚学习完ARM架构/组装。如果SP寄存器保存下一个要将数据放入的内存位置的地址,那么什么保存堆的地址?例如,在C++中,如果在堆上声明对象(例如, MyObjStase= NeXMyObjor);,程序集看起来是什么样子,从哪里可以知道代码>实例是什么?< P>登记器通常用于跟踪堆栈中的当前位置。这意味着它几乎需要始终指向堆栈 对于堆来说,情况并非如此。当您需要访问变量时,该变量的地址将存储在应用程序的指针或其他内存引用中。在需要该地址时,可以使用寄存器进行引用。但是,哪个寄存器的细节不仅取

我刚刚学习完ARM架构/组装。如果SP寄存器保存下一个要将数据放入的内存位置的地址,那么什么保存堆的地址?例如,在C++中,如果在堆上声明对象(例如,<代码> MyObjStase= NeXMyObjor);,程序集看起来是什么样子,从哪里可以知道代码>实例是什么?

< P>登记器通常用于跟踪堆栈中的当前位置。这意味着它几乎需要始终指向堆栈

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

在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和所有其他被调用者保存的寄存器,您可以在返回调用者之前记住恢复它们的值的同时,尽可能多地抓取它们

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


通常,根据程序和环境的不同,您可以使用各种黑客和工具进行优化,例如故意损坏一些非暂存寄存器并侥幸逃脱,但是您必须在调用方函数中管理这些寄存器,并且它应该知道在后续函数调用中将被暂存的寄存器,因此,EABI可能只有在将控制转移到另一个程序或接管时才有意义,您可以在cpu上做您喜欢做的事情,只需确保它保持在您进入该位置之前的干净状态。

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

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

这是编译器的实现细节。寄存器是CPU需要知道的东西。有一个SP寄存器,因为CPU有特殊的硬件,可以自动处理堆栈(例如,在发生中断时保存上下文)。CPU不知道也不关心堆。堆不是硬件,堆栈是。heep和堆内的分配与语言和库相关(与硬件无关)。@TJD:On ARM上硬件不会在堆栈上保存任何内容。CPU将重命名寄存器以切换到中断上下文。在32位ARM中,ISA SP只是R13的别名。事实上,它是“唯一”指定用作堆栈指针的ABI。我刚刚完成学习。。。我这一周看到的最有趣的短语PCome想一想为什么寄存器15(或ARM的任何内容)是SP?为什么不登记呢?它有多快?为什么不是SP?堆栈需要一个受调用和返回影响的专用寄存器,该寄存器是SP。但是有什么区别呢。堆栈需要专用寄存器,而不是堆?R15是PC,R14 LR和R13是SP。将堆栈指针保留在寄存器中只是函数分配临时空间的一种非常方便的方法。这是经常需要的。否则,每一小块内存都需要一些全局存储,这可能会成为一个真正的性能问题。@Celeritas关于为什么将
r13
用作堆栈指针的问题的答案部分是约定的,部分原因是ARM CPU有一个寄存器子集,这些寄存器在IRQ和FIQ模式下都有阴影——这两种中断模式都需要快速且需要单独的堆栈。如果事实上,在具有完全内存保护的系统(如Linux)上,这不是一个很大的问题,因此选择完全是约定的。好吧,那么你是说在CPU级别上没有堆的概念?是的,正是这样。必须允许您使用任何正在播放(读/写)的内存来执行此操作。这就是操作系统的帮助所在,你可以通过malloc分配一些内存,或者你的应用程序已经以可执行二进制文件的形式告诉操作系统它需要多少内存。然后,当你使用内存时,你开始去引用包含允许你玩的区域地址的寄存器。在ARM上,也没有什么能像真正的硬件支持堆栈那样。在这方面,它与x86非常不同。CPU本身并不真正知道什么是“堆栈”。您还需要操作系统对堆栈区域的支持,因为如果需要,内核必须增加堆栈。@Masta79,+1。CPU不支持堆栈,而是EAB