【问题标题】:How can I see string value in stack?如何查看堆栈中的字符串值?
【发布时间】:2020-02-26 13:46:12
【问题描述】:

我有以下汇编代码。

我可以在“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
--------------|--------------

低于 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?

【问题讨论】:

    标签: assembly gdb


    【解决方案1】:

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

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

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

    【讨论】:

    • 谢谢。我不明白 LEA 和 MOV 之间的区别。我试过 (char**) 但它没有显示我预期的值。
    • @zono 也许*(char **)address 取消引用。我没试过。
    猜你喜欢
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 2021-12-01
    • 2011-07-24
    • 2014-05-31
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    相关资源
    最近更新 更多