【发布时间】:2019-04-19 07:28:59
【问题描述】:
在尝试了解进程中的内存布局并学习汇编时,我在 Pi3 (ARM) 上编写了一个基本的 C 程序并使用 GDB 将其反汇编,但由于我是新手,因此我需要帮助理解它。
基本上,我试图了解和发现程序集中存储变量的位置(BSS、DATA、TEXT 内存段),并了解并遵循堆栈帧。
我只显示了主要功能 - 调试屏幕上还有其他部分,所以如果他们也有帮助,请告诉我!
我了解各个指令的大部分内容,但我想知道的是:
前3行与栈指针有关,这是为main函数设置栈帧吗?
在 x0x10414 它使用年龄的值,这是局部变量作为主函数框架的一部分弹出到堆栈的地方吗?
在 x0x1041c 处,我假设的返回值是否也作为帧的一部分被推入堆栈?
函数末尾刷新的栈在哪里?
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
【问题讨论】:
-
堆栈没有“刷新”,这是一个相当普遍的误解。堆栈指针恢复到调用函数之前的值,函数在堆栈上创建的值被视为垃圾,可能/将被进一步的代码执行覆盖。
-
这里使用了帧指针,因此堆栈指针仅用于保存帧指针。调用者假设帧指针将保持原样,因此我们必须保留并恢复它。我们还必须保留堆栈指针并将其恢复为其原始值,但堆栈本身我们不需要。