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



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

从本质上讲,我试图理解和发现程序集中存储变量的位置(BSS、数据、文本内存段),并理解并遵循堆栈帧。

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

我了解各个说明在大多数情况下都在做什么,但我想知道的是:

  1. 前 3 行与堆栈指针有关,这是为 main 函数设置堆栈帧吗?

  2. 在 x0x10414 处,它使用的是年龄值,这是局部变量作为主函数帧的一部分弹出到堆栈上的地方吗?

  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   
  1. 是的,你是对的。寄存器r11用作帧指针。此帧指针用作局部变量在堆栈上的存储位置的参考。请注意,必须保留来自调用方的原始帧指针(以便稍后保存和还原)。
  2. 几乎。它发生在一行之后,它将其存储在 [r11 - 8] 的堆栈上。 请记住,r11是帧指针,一切都是相对的。
  3. 它不会推送到堆栈上。它只是在寄存器r0中返回。 在许多平台上,使用通用寄存器是很常见的。然后,堆栈不需要用于简单和普通的返回值(如整数)。我想这是出于性能原因,因为寄存器比内存访问更快。
  4. 我不知道你说的脸红是什么意思。这里发生的事情是,该函数按照它喜欢的方式设置内容,然后还原这些更改。堆栈的内容可能仍包含函数使用的值。只是指针被重置到其原始位置。首先在函数的开头,原始帧指针(r11)被保存/推送到堆栈上。 然后,堆栈指针的值将成为新的帧指针。 在函数结束时,堆栈指针返回到它原来的位置(通过用r11覆盖它),最后r11通过将其从堆栈中弹出来恢复自身。

最新更新