ARM:链接寄存器和帧指针 [英] ARM: link register and frame pointer

查看:306
本文介绍了ARM:链接寄存器和帧指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解如何链接寄存器和ARM帧指针的工作。我去过一对夫妇的网站,我想确认我的理解。

I'm trying to understand how the link register and the frame pointer work in ARM. I've been to a couple of sites, and I wanted to confirm my understanding.

假设我有以下code:

Suppose I had the following code:

int foo(void)
{
    // ..
    bar();
    // (A)
    // ..
}

int bar(void)
{
    // (B)
    int b1;
    // ..
    // (C)
    baz();
    // (D)
}

int baz(void)
{
    // (E)
    int a;
    int b;
    // (F)
}

和我调用foo()。将链接寄存器包含点(A)的地址为code和帧指针包含在code点(B)地址?和堆栈指针就可以在任何地方内杆(),毕竟当地人已被宣布?

and I call foo(). Would the link register contain the address for the code at point (A) and the frame pointer contain the address at the code at point (B)? And the stack pointer would could be any where inside bar(), after all the locals have been declared?

感谢

增加了一个函数调用巴兹()

[edit] Added another function call baz()

推荐答案

一些寄存器调用约定依赖于 ABI (应用程序二进制接口)。在ARM上最常见当前是<一个href=\"http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0036b/index.html\">EABI.如果一个函数静态,编译器真的没有遵守任何规则。 [本段可以忽略不计,它只是意味着所有的规则可以被打破。

Some register calling conventions are dependent on the ABI (Application Binary Interface). The most common current one on the ARM is the EABI. If a function is static, a compiler really doesn't have to adhere to any conventions. [This paragraph can be ignored, it just means all rules can be broken].

通常,所有的ARM寄存器的通用的。在 LR (链接寄存器,也R14)和 PC (程序计数器也R15)是特殊的,在指令奉祀组。你是正确的,因为 LR 将指向为 A 。在 PC LR 有关。一个是你在哪里,另一个是你在哪里。他们是在 code 功能的一个方面。

Generally all ARM registers are general purpose. The lr (link register, also R14) and pc (program counter also R15) are special and enshrine in the instruction set. You are correct that the lr would point to A. The pc and lr are related. One is "where you are" and the other is "where you were". They are the code aspect of a function.

通常情况下,我们有 SP (堆栈指针,R13)和 FP (<一个href=\"http://stackoverflow.com/questions/10928646/whats-the-equivalent-of-bp-register-frame-pointer-on-arm-processors\">frame指针,R11)。这两个也有关系。这个
微软布局做得很好描述事物。该的用于堆栈存储在函数的临时数据或的当地人的。在 foo的任何变量()巴(),都保存在这里,堆栈或可用寄存器。在 FP 跟踪从函数的变量的功能。这是一个的的或图片窗口堆叠该功能上。在 ABI 的定义此的的布局。通常情况下, LR 和其它寄存器保存在这里编译器的场景以及的previous价值背后 FP 。这使得栈帧的链表的,如果你愿意,你可以跟踪它所有的方式回到的main()。在的是 FP ,它指向一个堆栈帧(如结构)与在结构作为previous FP 一个变量。您可以沿着列表去,直到最后的 FP 这通常是 NULL

Typically, we have the sp (stack pointer, R13) and the fp (frame pointer, R11). These two are also related. This Microsoft layout does a good job describing things. The stack is used to store temporary data or locals in your function. Any variables in foo() and bar(), are stored here, on the stack or in available registers. The fp keeps track of the variables from function to function. It is a frame or picture window on the stack for that function. The ABI defines a layout of this frame. Typically the lr and other registers are saved here behind the scenes by the compiler as well as the previous value of fp. This makes a linked list of stack frames and if you want you can trace it all the way back to main(). The root is fp, which points to one stack frame (like a struct) with one variable in the struct being the previous fp. You can go along the list until the final fp which is normally NULL.

所以 SP 是堆栈和 FP 是堆栈是,很像 PC LR 。每个老 LR (链接寄存器)存储在旧 FP (帧指针)。在 SP FP 数据的功能方面。

So the sp is where the stack is and the fp is where the stack was, a lot like the pc and lr. Each old lr (link register) is stored in the old fp (frame pointer). The sp and fp are a data aspect of functions.

您点的是活动 PC SP 。点的 A 其实就是 FP LR ;除非你调用另一个函数,然后编译器可能准备来设置 FP 指向数据的

Your point B is the active pc and sp. Point A is actually the fp and lr; unless you call yet another function and then the compiler might get ready to setup the fp to point to the data in B.

以下是可能证明这一切是如何工作的一些ARM汇编。这将是不同,这取决于编译器如何优化,但它应该给一个想法,

Following is some ARM assembler that might demonstrate how this all works. This will be different depending on how the compiler optimizes, but it should give an idea,

; Prologue - setup
mov     ip, sp                 ; get a copy of sp.
stm     sp!, {fp, ip, lr, pc}  ; Save the frame on the stack. See Addendum
sub     fp, ip, #4             ; Set the new frame pointer.
    ...
; Maybe other functions called here.
; Older caller return lr stored in stack frame. bl baz ... ; Epilogue - return ldm sp, {fp, sp, lr} ; restore stack, frame pointer and old link. ... ; maybe more stuff here. bx lr ; return.


这是富()会是什么样子。如果你不叫巴(),那么编译器做了的叶优化的,并不需要保存的的;只有 BX LR 是必要的。这很可能,也许你为什么要通过网络的例子混淆。它并不总是相同的。

This is what foo() would look like. If you don't call bar(), then the compiler does a leaf optimization and doesn't need to save the frame; only the bx lr is needed. Most likely this maybe why you are confused by web examples. It is not always the same.

外卖应该是,


  1. PC LR 相关的 code 寄存器。一个是你在哪里,另一个是你在哪里。

  2. SP FP 相关的本地数据寄存器。
    一是哪里本地数据是,另一种是哪里最后一个本地数据是

  3. 一起随着<一个工作href=\"http://stackoverflow.com/questions/261419/arm-to-c-calling-convention-registers-to-save\">parameter通过打造的功能的机械。

  4. 这是很难描述一般的情况下,因为我们希望编译器那样的快速越好,这样他们利用每一个技巧,他们可以。

  1. pc and lr are related code registers. One is "Where you are", the other is "Where you were".
  2. sp and fp are related local data registers.
    One is "Where local data is", the other is "Where the last local data is".
  3. The work together along with parameter passing to create function machinery.
  4. It is hard to describe a general case because we want compilers to be as fast as possible, so they use every trick they can.

这些概念是通用于所有的CPU和编译语言,虽然细节可以改变。使用的链接寄存器帧指针的是函数序言的一部分和尾声,如果你什么都明白了,你知道怎么的堆栈溢出的工作在ARM。

These concepts are generic to all CPUs and compiled languages, although the details can vary. The use of the link register, frame pointer are part of the function prologue and epilogue, and if you understood everything, you know how a stack overflow works on an ARM.

另请参阅: ARM调用约定
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; MSDN ARM堆栈文章

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
/~fms27/teaching/2001-02/arm-project/02-sort/apcs.txt\">University
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
ARM堆栈跟踪博客

&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; <一href=\"https://developer.apple.com/library/ios/documentation/X$c$c/Conceptual/iPhoneOSABIReference/Articles/ARMv6FunctionCallingConventions.html\">Apple ABI链接

See also: ARM calling convention.
                MSDN ARM stack article
                University of Cambridge APCS overview
                ARM stack trace blog
                Apple ABI link

的基本框架布局,


  • FP [-0]保存 PC ,我们存储在此框架。

  • FP [-1]保存 LR ,返回地址此功能。

  • FP [-2] previous SP ,此函数之前的的协议栈。

  • FP [-3] previous FP ,最后的堆栈帧

  • 许多可选寄存器...

  • fp[-0] saved pc, where we stored this frame.
  • fp[-1] saved lr, the return address for this function.
  • fp[-2] previous sp, before this function eats stack.
  • fp[-3] previous fp, the last stack frame.
  • many optional registers...

ABI 可以使用其它的值,但以上是典型的大多数设置。

An ABI may use other values, but the above are typical for most setups.

附录:这是不是在汇编程序的错误;这是正常的。一种解释是在 ARM产生prologs 问题。

Addendum: This is not an error in the assembler; it is normal. An explanation is in the ARM generated prologs question.

这篇关于ARM:链接寄存器和帧指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆