理解GDB中基本C程序中的asm指令

问题描述 投票:3回答:1

在我尝试理解一个过程中的内存布局并学习汇编时,我已经在Pi3(ARM)上编写了一个基本的C程序,并用GDB对其进行了反汇编,但由于我是新手,我需要帮助理解它。

本质上,我试图理解并发现存储变量的汇编(BSS,DATA,TEXT内存段),并理解并遵循堆栈帧。

我只显示了主要功能 - 调试屏幕上还有其他部分,所以让我知道他们是否也会有所帮助!

我理解大部分指令在做什么,但我想知道的是:

  1. 前三行是关注堆栈指针,这是为主函数设置堆栈帧吗?
  2. 在x0x10414,它使用了age的值,这是将局部变量作为主函数框架的一部分弹出到堆栈中的位置吗?
  3. 在x0x1041c是我假设的返回值也是作为帧的一部分被推入堆栈的?
  4. 堆栈在函数末尾刷新到哪里?
int main () {
        int age = 30;
        int salary;
        return 0;
}
0x10408 <main>                  push   {r11}           ; (str r11, [sp, #-4]!)
x0x1040c <main+4>               add    r11, sp, #0                           
x0x10410 <main+8>               sub    sp, sp, #12                           
x0x10414 <main+12>              mov    r3, #30                               
x0x10418 <main+16>              str    r3, [r11, #-8]                        
x0x1041c <main+20>              mov    r3, #0                                
x0x10420 <main+24>              mov    r0, r3                                
x0x10424 <main+28>              add    sp, r11, #0                           
x0x10428 <main+32>              pop    {r11}           ; (ldr r11, [sp], #4) 
x0x1042c <main+36>              bx     lr   
c assembly arm
1个回答
3
投票
  1. 是的,你是对的。寄存器r11用作帧指针。此帧指针用作对局部变量存储在堆栈中的引用。请注意,必须保留来自调用者的原始帧指针(以便稍后保存和恢复)。
  2. 几乎。它发生在一行之后,它将它存储在[r11 - 8]的堆栈中。请记住,r11是帧指针,一切都是相对的。
  3. 它没有被推到堆栈上。它只是在寄存器r0中返回。在许多平台上使用通用寄存器是很常见的。然后堆栈不需要用于简单和普通的返回值(如整数)。我想这是出于性能原因,因为寄存器比内存访问更快。
  4. 我不知道你的意思是脸红了。这里发生的是该函数按照自己喜欢的方式设置,然后恢复这些更改。堆栈的内容可能仍包含函数使用的值。只是将指针重置为原始位置。首先在函数的开头,原始帧指针(r11)被保存/推入堆栈。然后堆栈指针的值成为新的帧指针。在函数结束时,堆栈指针返回到它所在的位置(通过用r11覆盖它),最后r11本身也通过从堆栈中弹出来恢复。
© www.soinside.com 2019 - 2024. All rights reserved.