Wrote simple program with large buffer in .bss segment
h_vals:
resq 99999
then tried to increment value of some array cell.
mov rcx, [h_vals+8*rax]
inc rcx
mov [h_vals+8*rax], rcx
Still in gdb see the same value(0) both before and after third instruction execution.
x/dg &h_vals &h_vals + 8 * $rax
0x6d68c0: 0
Why am I still seeing 0 when I try to inspect the address I stored to?
mov
obviously does move data; Your program would segfault if it failed.
The default size for symbols with no debug info is 4 bytes. You can use ptype h_vals
to check what gdb thinks about it.
Remember that gdb's syntax works like C, even if you're debugging asm. In C, adding something to a pointer offsets by that many elements, not that many bytes.
&h_vals &h_vals + 8 * $rax
isn't evaluating in gdb to the address you expect. (Also, I think &h_vals &h_vals
is a typo, and isn't what you actually ran.)
Since gdb thinks &h_vals
is an int*
, &h_vals + offset
will produce a byte offset of 4 * offset, just like h_vals[offset]
in C. So the address you're ex
amining in gdb is actually [h_vals + 8 * 4 * rax]
.
Another way to check: p /x &h_vals
and p /x $rax
separately. You can work out the math yourself and compare to the address you saw in the x/
output.
The safest solution here is to cast to char*
:
x /dg 8 * $rax + (char*)&h_vals
Or: define your symbols in a .c
so the compiler will generate debug info for them (because you don't want to do that by hand).
e.g. put unsigned long h_vals[99999];
in a .c that you compile with gcc -c -g vars.c
, and link the resulting .o with the .o YASM creates from your .asm.