为什么 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
我正在尝试 运行 一个简单的汇编代码 - 我想将地址保存到内存中。
我正在将地址移动到寄存器中,然后将其移动到内存中,但由于某种原因,内存没有更新。
.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