如何查看堆栈中的字符串值?

时间:2019-10-31 08:22:15

标签: assembly gdb

我有以下汇编代码。

我可以在“ lea”之后看到“%rax”寄存器中的字符串值-(A)

(gdb) p (char*)0x558efff0a010
$1 = 0x558efff0a010 "abc"

但是,“移动”后,我看不到堆栈中的值-(B)

(gdb) p (char*)0x7fff2754b2a8
$2 = 0x7fff2754b2a8 "\020\240\360\377\216U"

我想念什么吗?

汇编代码

.data
.L0:
    .string "abc"
    .text
    .global f
f:
    push %rbp
    mov %rsp, %rbp
    sub $8, %rsp
    lea .L0(%rip), %rax -- (A)
    mov %rax, -8(%rbp) -- (B)
    leave
    ret

主要:

rax            0x558effd095fa   94072665576954
rbp            0x7fff2754b2c0   0x7fff2754b2c0
rsp            0x7fff2754b2c0   0x7fff2754b2c0

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                        <= rbp, rsp
--------------|--------------

f()

rax            0x0  0
rbp            0x7fff2754b2c0   0x7fff2754b2c0
rsp            0x7fff2754b2b8   0x7fff2754b2b8

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                        <= rbp
--------------|--------------
0x7fff2754b2b8|                       <= rsp
--------------|--------------

按%rbp

rax            0x0  0
rbp            0x7fff2754b2c0   0x7fff2754b2c0
rsp            0x7fff2754b2b0   0x7fff2754b2b0

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                       <= rbp
--------------|--------------
0x7fff2754b2b8|                      
--------------|--------------
0x7fff2754b2b0|                       <= rsp
--------------|--------------

mov%rsp,%rbp

rax            0x0  0
rbp            0x7fff2754b2b0   0x7fff2754b2b0
rsp            0x7fff2754b2b0   0x7fff2754b2b0

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                       
--------------|--------------
0x7fff2754b2b8|                      
--------------|--------------
0x7fff2754b2b0|                      <= rbp, rsp
--------------|--------------

sub $ 8,%rsp

rax            0x0  0
rbp            0x7fff2754b2b0   0x7fff2754b2b0
rsp            0x7fff2754b2a8   0x7fff2754b2a8

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                       
--------------|--------------
0x7fff2754b2b8|                      
--------------|--------------
0x7fff2754b2b0|                      <= rbp
--------------|--------------
0x7fff2754b2a8|                      <= rsp
--------------|--------------

lea .L0(%rip),%rax

rax            0x558efff0a010   94072667676688
rbp            0x7fff2754b2b0   0x7fff2754b2b0
rsp            0x7fff2754b2a8   0x7fff2754b2a8

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                       
--------------|--------------
0x7fff2754b2b8|                      
--------------|--------------
0x7fff2754b2b0|                      <= rbp
--------------|--------------
0x7fff2754b2a8|                      <= rsp
--------------|--------------

(gdb) p (char*)0x558efff0a010
$1 = 0x558efff0a010 "abc"

mov%rax,-8(%rbp)

rax            0x558efff0a010   94072667676688
rbp            0x7fff2754b2b0   0x7fff2754b2b0
rsp            0x7fff2754b2a8   0x7fff2754b2a8

--------------|--------------
ADDRESS       |VALUE
--------------|--------------
0x7fff2754b2c0|                       
--------------|--------------
0x7fff2754b2b8|                      
--------------|--------------
0x7fff2754b2b0|                      <= rbp
--------------|--------------
0x7fff2754b2a8|                      <= rsp
--------------|--------------

(gdb) p (char*)0x7fff2754b2a8
$2 = 0x7fff2754b2a8 "\020\240\360\377\216U"

更新1

我尝试了(char **)

rax            0x55b1ef3cc010   94222711308304
rsp            0x7ffd7fcd8cc8   0x7ffd7fcd8cc8

(gdb) p (char*)0x55b1ef3cc010
$3 = 0x55b1ef3cc010 "abc"

(gdb) p (char**)0x7ffd7fcd8cc8
$2 = (char **) 0x7ffd7fcd8cc8

正如@Peter Cordes所说,我发现LEA和MOV之间存在差异。

  
      
  • LEA表示加载有效地址

  •   
  • MOV表示加载值

  •   

What is the difference between MOV and LEA?

1 个答案:

答案 0 :(得分:2)

字符串数据仍然仅位于绝对地址0x558efff0a010

您刚刚在堆栈上存储了一个指针,然后告诉GDB将该指针值的字节打印为字符串。如果对八进制\020\240\360\377\216U进行解码,请注意八进制020 = 2 * 8是十六进制0x10 = 1 * 16,即指针的第一个字节(小尾数)。

也许您希望*(char **)0x7fff2754b2a8取消引用堆栈地址并从该内存位置获取一个char*