我是asm的新手。我试图在Linux 64位上使用NASM将指针从寄存器复制到.data
变量。
Concider这个程序:
section .data
ptr: dq 0
section .text
global _start
_start:
mov [ptr], rsp
mov rax, 60
mov rdi, 0
syscall
这里我尝试将当前堆栈指针复制到ptr
。 ptr
被声明为四字。 nasm
和链接器都没有抱怨,但是在使用gdb调试程序时,我发现两个地址都不同:
gdb ./test.s
+(gdb) break _start
Breakpoint 1 at 0x4000b0
+(gdb) run
Starting program: test
Breakpoint 1, 0x00000000004000b0 in _start ()
+(gdb) nexti
0x00000000004000b8 in _start ()
+(gdb) info registers
...
rsp 0x7fffffffe460 0x7fffffffe460
...
+(gdb) x ptr
0xffffffffffffe460: Cannot access memory at address 0xffffffffffffe460
根据我的理解,mov
应该将rsp
的所有64位复制到[ptr]
,但似乎不会复制最重要的0
和/或有某种符号扩展,好像只复制了最低有效位。
答案 0 :(得分:3)
问题是,您没有ptr
类型的调试信息,因此gdb
将其视为整数。您可以使用以下方法检查其实际内容:
(gdb) x/a &ptr
0x600124 <ptr>: 0x7fffffffe950
(gdb) p/a $rsp
$3 = 0x7fffffffe950
当然,rsp
的值与您不同,但您可以看到ptr
和rsp
匹配。
答案 1 :(得分:1)
看起来你错误地使用了gdb:
section .data
ptr: dq 0
section .text
global main
main:
mov [ptr], rsp
ret
编译:
rm -f test.o && nasm -f elf64 test.asm && gcc -m64 -o test test.o
然后我的调试会话看起来像这样:
gdb ./test
(...)
(gdb) break main
Breakpoint 1 at 0x4004c0
(gdb) run
Starting program: /home/rr-/test
Breakpoint 1, 0x00000000004004c0 in main ()
(gdb) nexti
0x00000000004004c8 in main ()
(gdb) info registers
rax 0x4004c0 4195520
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffe388 140737488348040
rsi 0x7fffffffe378 140737488348024
rdi 0x1 1
rbp 0x4004d0 0x4004d0 <__libc_csu_init>
rsp 0x7fffffffe298 0x7fffffffe298
(...)
(gdb) info addr ptr
Symbol "ptr" is at 0x600880 in a file compiled without debugging.
(gdb) x/g 0x600880
0x600880: 140737488347800
140737488347800评估为0x7FFFFFFFE298就好了。
答案 2 :(得分:-1)
+(gdb) x/h ptr
h
表示半字,即两个字节。您想要的可能是g
(GDB术语中的巨型词,即八个字节)。