Assembly ARM子例程调用和链接寄存器使用

Assembly ARM子例程调用和链接寄存器使用,assembly,arm,Assembly,Arm,每个函数调用都会产生堆栈帧和当前PC值,并将其推送到堆栈上。在函数返回期间展开堆栈时,PC值(返回地址)可以从堆栈帧加载到PC上。如果是这样,对链接寄存器(LR)的需求是什么。执行BL或BLX时,返回地址存储在链接寄存器中。这样可以访问返回地址,以便将其推送到堆栈上(而不是直接推送的调用指令) 在叶函数中(无其他子调用),不需要保存返回地址。通过跳转到链接寄存器中的地址即可实现返回: bx-lr可以设计不带链接寄存器的处理器。这种体系结构的一个例子是x86,其中函数调用直接在堆栈上推送返回地址,

每个函数调用都会产生堆栈帧和当前PC值,并将其推送到堆栈上。在函数返回期间展开堆栈时,PC值(返回地址)可以从堆栈帧加载到PC上。如果是这样,对链接寄存器(LR)的需求是什么。

执行BL或BLX时,返回地址存储在链接寄存器中。这样可以访问返回地址,以便将其推送到堆栈上(而不是直接推送的调用指令)

在叶函数中(无其他子调用),不需要保存返回地址。通过跳转到链接寄存器中的地址即可实现返回:


bx-lr

可以设计不带链接寄存器的处理器。这种体系结构的一个例子是x86,其中函数调用直接在堆栈上推送返回地址,而函数返回直接从堆栈上拾取返回地址

对于这种设计,拥有链接寄存器只是一种不同的选择。虽然这不是一个特别新颖的想法(例如,1960年代的IBM s/360已经有了这个概念),但RISC处理器设计学院已经普及了链路寄存器,因为它们降低了函数调用和返回指令的复杂性,使得处理器更容易设计,并且由于所需晶体管的数量减少,可能更快


链接寄存器的另一个优点是,不调用其他函数(叶函数)的函数可以不在堆栈上存储返回地址。这将在每次执行函数时节省一个加载和一个存储,当函数较短时,这将大大节省时间。

增加或拥有足够的寄存器,以便可以存储前几个传递的参数,并且链接寄存器避免了堆栈,这是一种性能成本(与基于堆栈的参数和/或返回地址解决方案相比)。如果叶函数使用很少的变量(根本不需要堆栈),则这一点会更好。根据体系结构,一旦你承诺进行堆栈访问,一个额外的时钟周期(即保存4个寄存器而不是2个寄存器)并不像一般的访问开销那么大。我认为这是内存访问,而不是晶体管…@old_timer你可以使用堆栈引擎或内存opera来消除内存访问nd重命名。通常情况下,你还是会推送返回地址,因此将其与呼叫相结合可以节省简化处理器设计的时间(你会得到一些东西来填补讨厌的分支延迟槽)risc背后的思想通常是通过增加通用寄存器的数量和简化来避免或减少内存访问,这样许多事情就可以在寄存器中完成,而不需要访问内存。risc中逻辑的简化来自于指令的简化,fewe需要r状态机(不需要微代码,加上微代码的类似risc的状态机)等等。对于cisc和risc,内存访问是相同的,类似的状态机,您启动并等待卓越简洁的答案。出于任何原因,我们希望使用寄存器而不是堆栈帧,因为有时您可以部分或全部避免堆栈帧。
myfunc:
 push {lr} ;saves return address
 ...
 pop {pc} ; returns to saved value