NASM: 将指针从寄存器复制到 .data 中的缓冲区

NASM: copying a pointer from a register to a buffer in .data

我是 asm 的新手。我正在尝试在 linux 64 位上使用 NASM 将指针从寄存器复制到 .data 变量。

考虑这个程序:

    section .data
ptr: dq 0

    section .text
    global _start

_start:
    mov [ptr], rsp

    mov rax, 60
    mov rdi, 0
    syscall

这里我尝试将当前栈指针复制到ptrptr 声明为四字。 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 应该将所有 64 位从 rsp 复制到 [ptr],但似乎最重要的 0 没有被复制 and/or 有某种符号扩展,好像只复制了最低有效位。

+(gdb) x/h ptr

h表示half-word,也就是两个字节。你要的大概是g(GDB术语中的Giant words,也就是八个字节)。

问题是,您没有 ptr 类型的调试信息,因此 gdb 将其视为整数。您可以使用以下方法检查其真实内容:

(gdb) x/a &ptr
0x600124 <ptr>: 0x7fffffffe950
(gdb) p/a $rsp
 = 0x7fffffffe950

当然我对 rsp 的值与你不同,但你可以看到 ptrrsp 匹配。

看来你对我的 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 就好了。