Gdb 手臂拆卸说明

Gdb 手臂拆卸说明,gdb,arm,raspberry-pi,raspbian,Gdb,Arm,Raspberry Pi,Raspbian,我刚刚设置了一个raspberry pi机器,并尝试对下面的代码进行反向工程 #include<stdio.h> int main() { printf("this is a test\n"); } #包括 int main(){ printf(“这是一个测试\n”); } 在大多数情况下,gdb中的以下反汇编似乎是有意义的 0x000083c8 <+0>: push {r11, lr} 0x000083cc <+4>: add r11,

我刚刚设置了一个raspberry pi机器,并尝试对下面的代码进行反向工程

#include<stdio.h>
int main() {
printf("this is a test\n");
}
#包括
int main(){
printf(“这是一个测试\n”);
}
在大多数情况下,gdb中的以下反汇编似乎是有意义的

   0x000083c8 <+0>: push    {r11, lr}
   0x000083cc <+4>: add r11, sp, #4
   0x000083d0 <+8>: ldr r0, [pc, #8]    ; 0x83e0 <main+24>
   0x000083d4 <+12>:    bl  0x82ec <puts>
   0x000083d8 <+16>:    mov r0, r3
   0x000083dc <+20>:    pop {r11, pc}
   0x000083e0 <+24>:    andeq   r8, r0, r4, asr r4
0x000083c8:push{r11,lr}
0x000083C:添加r11,sp,#4
0x000083d0:ldr r0,[pc,#8];0x83e0
0x000083d4:bl 0x82ec
0x000083d8:mov r0,r3
0x000083dc:pop{r11,pc}
0x000083e0:andeq r8、r0、r4、asr r4
  • 但是,我无法理解为什么
    0x000083e0
    处的指令存在。这个指令甚至是主要功能的一部分吗?在0x000083c8中输入的值不会弹出到pc中,立即将控制权转移到其他位置吗
  • 我还尝试将断点设置为0x000083e0——我似乎遇到了一个非常奇怪的错误。为什么会这样

  • 调用此函数时(即在指令
    0x000083c8
    开始执行时),链接寄存器(LR)应已包含返回地址。快进到
    0x000083d8
    :根据ARM C调用约定(,)将puts函数的返回结果置于R0中。然后,返回地址从堆栈弹出到PC中,有效地结束了此函数的执行。这意味着
    0x000083e0
    处的指令不是程序的一部分,您的检查应限于
    0x000083c8
    0x000083dc
    的指令

    因此,要回答您的问题:

  • 0x000083e0
    处的“指令”基本上是垃圾。根据ARM内核的具体情况,您甚至可能没有执行和/或访问此内存的权限(是否有MMU等?)。因此,当尝试检查该位置时,seg故障是合理的结果
    编辑:与下面的注释一致,
    0x000083e0
    的内容应解释为数据,而不是说明

    调用此函数时(即在指令
    0x000083c8
    开始执行时),链接寄存器(LR)应该已经包含返回地址。快进到
    0x000083d8
    :根据ARM C调用约定(,)将puts函数的返回结果置于R0中。然后,返回地址从堆栈弹出到PC中,有效地结束了此函数的执行。这意味着
    0x000083e0
    处的指令不是程序的一部分,您的检查应限于
    0x000083c8
    0x000083dc
    的指令

    因此,要回答您的问题:

  • 0x000083e0
    处的“指令”基本上是垃圾。根据ARM内核的具体情况,您甚至可能没有执行和/或访问此内存的权限(是否有MMU等?)。因此,当尝试检查该位置时,seg故障是合理的结果
    编辑:与下面的注释一致,
    0x000083e0
    的内容应解释为数据,而不是说明

    0x000083e0处的四个字节不是垃圾。它是PC相对负载的一部分

    0x000083d0 <+8>: ldr r0, [pc, #8]    ; 0x83e0 <main+24>
    
    0x000083d0:ldr r0,[pc,#8];0x83e0
    
    它在注释中也可见,如
    ;0x83e0


    这里的问题因为您需要将字符串的地址传递给
    put
    ,其地址在链接步骤中可能会更改,所以编译器需要为这种进一步的处理创建合适的代码。因此,字符串的地址在指令流中结束,但在任何执行上下文之外。

    0x000083e0处的四个字节不是垃圾。它是PC相对负载的一部分

    0x000083d0 <+8>: ldr r0, [pc, #8]    ; 0x83e0 <main+24>
    
    0x000083d0:ldr r0,[pc,#8];0x83e0
    
    它在注释中也可见,如
    ;0x83e0


    这里的问题因为您需要将字符串的地址传递给
    put
    ,其地址在链接步骤中可能会更改,所以编译器需要为这种进一步的处理创建合适的代码。所以字符串的地址在指令流中结束,但在任何执行上下文之外。

    0x000083e0实际上不是垃圾。由于它的内容在调用puts之前加载到R0,因此它应该包含
    “这是一个测试”
    stringCorrection:LR不保存在R11中。LR和R11(帧指针)保存在堆栈上。此外,
    andeq r8、r0、r4、asr r4
    是值0x00008454的“反汇编”。现在,那看起来像什么…;)0x000083e0不是真正的垃圾。由于它的内容在调用puts之前加载到R0,因此它应该包含
    “这是一个测试”
    stringCorrection:LR不保存在R11中。LR和R11(帧指针)保存在堆栈上。此外,
    andeq r8、r0、r4、asr r4
    是值0x00008454的“反汇编”。现在,那看起来像什么…;)