为什么 SASM 的调试器不显示存储后更新的 "result" 变量的值?

Why doesn't SASM's debugger show the value of a "result" variable updating after a store?

我正在尝试 运行 一个简单的汇编代码 - 我想将地址保存到内存中。

我正在将地址移动到寄存器中,然后将其移动到内存中,但由于某种原因,内存没有更新。

.data 
str1: .asciz "atm course number is 234118"
str2: .asciz "234118"
result: .space 8

.text
.global main
main:
    xorq  %rax, %rax
    xorq %rbx, %rbx
    leaq str1, %rax
    mov %rax, result(,%rbx,1)
    ret

我做错了什么?

您的调试器正在查看 result 的错误实例。您的代码总是很好(尽管效率低下;使用 mov %rax, result(%rip) 并且不要将索引归零,或者使用 mov %rax, result(%rbx,,) 将字节偏移量用作 "base",而不是 "index",效率更高)。

glibc 包含几个 result 符号,在 GDB info var result 中显示:

All variables matching regular expression "result":

Non-debugging symbols:
0x000000000040404b  result         # in your executable, at a normal static address
0x00007ffff7f54f20  result_type
0x00007ffff7f821b8  cached_result
0x00007ffff7f846a0  result         # in glibc, at a high address
0x00007ffff7f85260  result         #  where the dynamic linker puts shared libs
0x00007ffff7f85660  result
0x00007ffff7f86ab8  result
0x00007ffff7f86f48  result

当我p /x &result查看调试器将该符号解析到哪个地址时,我得到了一个 glibc 实例,不是实例在你的 .data 部分。 具体来说,我得到 0x7ffff7f85660 作为地址,内容 = 0.

当我打印 value 并强制转换为 p /x (unsigned long)result 或使用 GDB 的 x 命令转储内存时,我发现 0 有后店。

(gdb) x /xg &result
0x7ffff7f85660 <result>:        0x0000000000000000

看起来您的系统选择了一个不同的实例,其中包含指向 libc 地址或其他内容的指针。我无法从您的图像中复制粘贴。这些其他 result 变量可能是 static int result 或 glibc 中各种 .c 文件中的任何内容。 (顺便说一句,这看起来像是编码风格不佳的标志;通常你想 return 一个值而不是设置一个全局或静态的值。但是 glibc 是旧的 and/or 也许其中一些有一些理由.)

您的 result: 是编译器为 static void* result 生成的 asm,如果它没有得到优化的话。除了它会把它放在 .bss 而不是 .data 中,因为它是零初始化的。


您正在使用 SASM。我使用 GDB 来获取更多关于到底发生了什么的详细信息。 在 SASM 的调试窗格中查看 result 的地址可能会有所帮助。但现在我们已经使用 GDB 确定了问题,我们可以更改您的源以针对 SASM 修复它。


您可以使用.globl result使其成为外部可见的符号,以便在调试器查找符号时"wins"。

我添加了它并用 gcc -g -no-pie store.s 再次编译。它现在按预期工作,p /x (unsigned long)result 给出 0x404028