用gdb反汇编时指针在哪里

时间:2019-02-24 00:43:50

标签: c debugging assembly gdb

当我在gdb中使用disas命令并使用以下代码时:

int main(){
   char*a;
   size_t r;
   return 1;
}

我得到这个结果:

0x080483db <+0>:    push   %ebp
0x080483dc <+1>:    mov    %esp,%ebp
0x080483de <+3>:    mov    $0x1,%eax
0x080483e3 <+8>:    pop    %ebp
0x080483e4 <+9>:    ret 

我不明白为什么char*asize*t没有说明。 如何获得a值和r值的地址?它们甚至存在吗?

3 个答案:

答案 0 :(得分:4)

声明char*a;size_t r;自己不做任何事情;他们宁愿告诉编译器您希望能够使用标识符ar来存储值,并且其生命周期仅限于main执行的持续时间。另一方面,大多数汇编说明(除了nops等)执行某些操作

如果您在这些变量中存储和访问值,或者获取了它们的地址并使用了这些地址,而这在某种意义上并不等同于什么都不做,那么您会看到编译器发出了腾出空间的代码(通常通过调整堆栈指针,或将某些寄存器推入堆栈以保存其值,以便为您的数据提供额外的可用寄存器)并存储/加载值。

答案 1 :(得分:0)

您需要进行实验,以使无效代码不会得到优化。

unsigned int fun0 ( void )
{
    return(0x12345678);
}
char * fun1 ( void )
{
    char *x;
    x = (char *)0x12345678;
    return(x);
}
unsigned int fun2 ( unsigned int x )
{
    return(x+12);
}
unsigned int * fun3 ( unsigned int *x )
{
    return(x+3);
}

给予类似的东西

Disassembly of section .text:

00000000 <fun0>:
   0:   e59f0000    ldr r0, [pc]    ; 8 <fun0+0x8>
   4:   e12fff1e    bx  lr
   8:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000

0000000c <fun1>:
   c:   e59f0000    ldr r0, [pc]    ; 14 <fun1+0x8>
  10:   e12fff1e    bx  lr
  14:   12345678    eorsne  r5, r4, #120, 12    ; 0x7800000

00000018 <fun2>:
  18:   e280000c    add r0, r0, #12
  1c:   e12fff1e    bx  lr

00000020 <fun3>:
  20:   e280000c    add r0, r0, #12
  24:   e12fff1e    bx  lr

答案 2 :(得分:0)

这里要注意的是C语言的as-if rule表示编译后的程序只需要产生相同的可观察的行为

由于程序的可观察行为与

相同
int main(){
    return 1;
}

这就是编译后的代码的作用。

这不仅适用于声明,而且可以任意复杂。例如常见的hello world程序:

#include <stdio.h>
int main(){
    printf("Hello world!\n");
}

具有可观察到的行为,等同于

#include <stdio.h>
int main(){
    puts("Hello world!");
}

后一个程序是使用-O3编译前一个程序时得到的结果:

.LC0:
    .string "Hello world!"
main:
    leaq    .LC0(%rip), %rdi
    subq    $8, %rsp
    call    puts@PLT
    xorl    %eax, %eax
    addq    $8, %rsp
    ret