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

546 Views Asked by At

I am new to asm. I am trying to copy a pointer from a register to a .data variable using NASM, on linux 64-bit.

Concider this program:

    section .data
ptr: dq 0

    section .text
    global _start

_start:
    mov [ptr], rsp

    mov rax, 60
    mov rdi, 0
    syscall

Here I try to copy the current stack pointer to ptr. ptr is declared as a quadword. Neither nasm nor the linker complains, but when debugging the program with gdb, I can see that both addresses are different:

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

From what I understand, mov should copy all 64 bits from rsp to [ptr], but it seems that the most significant 0s are not copied and/or that there is some kind of sign extension, as if only the least significant bits were copied.

3

There are 3 best solutions below

0
On BEST ANSWER

The problem is, you don't have debug info for the ptr type, so gdb treats it as integer. You can examine its real contents using:

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

Of course I have a different value for rsp than you, but you can see that ptr and rsp match.

0
On

Looks like you're using gdb wrongly to me:

    section .data
ptr: dq 0

    section .text
    global main

main:
    mov [ptr], rsp
    ret

Compiling with:

rm -f test.o && nasm -f elf64 test.asm && gcc -m64 -o test test.o

Then my debugging session looks like this:

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 evaluates to 0x7FFFFFFFE298 just fine.

1
On
+(gdb) x/h ptr

h means half-word, which is two bytes. What you want is probably g (Giant words in GDB terminology, which is eight bytes).