Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在GDB中理解basic C程序中的asm指令_C_Assembly_Arm - Fatal编程技术网

在GDB中理解basic C程序中的asm指令

在GDB中理解basic C程序中的asm指令,c,assembly,arm,C,Assembly,Arm,在我试图理解进程中的内存布局并学习汇编时,我已经在Pi3(ARM)上编写了一个基本的C程序,并用GDB对其进行了反汇编,但由于我是新手,我需要帮助理解它 从本质上讲,我试图理解和发现程序集中存储变量的位置(BSS、数据、文本内存段),并且理解和跟踪堆栈帧 我只显示了主功能-调试屏幕上还有其他部分,请告诉我它们是否也有帮助 我了解个人说明的大部分内容,但我想知道的是: 前3行与堆栈指针有关。这是否设置了主函数的堆栈框架 在x0x10414,它使用年龄值,局部变量作为主函数帧的一部分弹出到堆栈中吗

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

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

我只显示了主功能-调试屏幕上还有其他部分,请告诉我它们是否也有帮助

我了解个人说明的大部分内容,但我想知道的是:

  • 前3行与堆栈指针有关。这是否设置了主函数的堆栈框架

  • 在x0x10414,它使用年龄值,局部变量作为主函数帧的一部分弹出到堆栈中吗

  • 在x0x1041c处,我假设的返回值也是作为帧的一部分推送到堆栈上的吗

  • 在函数末尾刷新堆栈的位置

  • 0x10408推送{r11};(str r11,[sp,#-4]!)
    x0x1040c添加r11,sp,#0
    x0x10410子sp,sp,#12
    x0x10414 mov r3,#30
    x0x10418 str r3[r11,#-8]
    x0x1041c mov r3,#0
    x0x10420 mov r0,r3
    x0x10424添加sp,r11,#0
    x0x10428 pop{r11};(ldr r11,[sp],#4)
    x0x1042c bx lr
    
  • 是的,你说得对。寄存器
    r11
    用作帧指针。此帧指针用作局部变量在堆栈上存储位置的引用。请注意,必须保留调用者的原始帧指针(以便以后保存和还原)
  • 差不多。它发生在一行之后,它将其存储在堆栈的[r11-8]处。 请记住,
    r11
    是帧指针,所有内容都与之相关
  • 它不会被推到堆栈上。它只是在寄存器
    r0
    中返回。 在许多平台上,使用通用寄存器是很常见的。然后,堆栈不需要用于简单和普通的返回值(如整数)。我想这是出于性能原因,因为寄存器比内存访问速度快
  • 我不知道你对我是什么意思。这里发生的事情是函数按照它喜欢的方式进行设置,然后恢复这些更改。堆栈的内容可能仍然包含函数使用的值。只是指针被重置到它们原来的位置。首先,在函数的开头,原始帧指针(
    r11
    )保存/推送到堆栈上。 然后堆栈指针的值成为新的帧指针。 在函数结束时,堆栈指针返回到原来的位置(用
    r11
    覆盖它),最后将
    r11
    从堆栈中弹出,它本身也会恢复

  • 堆栈没有“刷新”,这是一个相当常见的误解。堆栈指针恢复到调用函数之前的值,函数在堆栈上创建的值被视为垃圾,可能/将被进一步的代码执行覆盖。此处使用的是帧指针,因此堆栈指针仅用于保留帧指针。调用方假定帧指针将保持调用时的状态,因此我们必须保留并恢复它。我们还必须将堆栈指针保留并恢复到其原始值,但堆栈本身却没有。
    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