2

I'm trying to run a simple code in assembly - I want to save an address to memory.

I'm moving the address into a register and then moving it into the memory, but for some reason the memory isn't updated.

.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

What am I doing wrong?

enter image description here

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
E. Ginzburg
  • 253
  • 2
  • 9
  • You don't need an index register; it would be more efficient to use `mov %rax, result(%rip)` (and not bother zeroing RBX) or `mov %rax, result(%rbx,,)` if you did want to use a byte offset. The latter only works in a non-PIE executable, but since your current code linked and ran we know that's what you have. – Peter Cordes Nov 23 '19 at 19:52
  • @PeterCordes thank for your answer but none of these worked... im still getting the same result - cant update thi place in memory... – E. Ginzburg Nov 23 '19 at 19:59
  • I didn't say that was the problem, sorry. Just that those are more efficient ways to do exactly the same thing. I was expecting to write another comment right away for some simple problem instead of leaving you hanging, but it was more tricky than I expected. – Peter Cordes Nov 23 '19 at 20:13

1 Answers1

3

Your debugger is looking at the wrong instance of result. Your code was always fine (although inefficient; use mov %rax, result(%rip) and don't zero an index, or use mov %rax, result(%rbx,,) to use the byte offset as a "base", not "index", which is more efficient).

glibc contains several result symbols, and in GDB info var result shows:

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

When I do p /x &result to see what address the debugger resolved that symbol to, I get one of the glibc instances, not the instance in your .data section. Specifically, I get 0x7ffff7f85660 as the address, with the content = 0.

When I print the value with a cast to p /x (unsigned long)result, or dump the memory with GDB's x command, I find a 0 there after the store.

(gdb) x /xg &result
0x7ffff7f85660 <result>:        0x0000000000000000

It looks like your system picked a different instance, one that contained a pointer to a libc address or something. I can't copy-paste from your image. These other result variables are probably static int result or whatever inside various .c files in glibc. (And BTW, that looks like a sign of poor coding style; usually you want to return a value instead of set a global or static. But glibc is old and/or maybe there's some justification for some of those.)

Your result: is the asm a compiler would make for static void* result if it didn't get optimized away. Except it would put it in .bss instead of .data because it's zero-initialized.


You're using SASM. I used GDB to get more details on exactly what's going on. Looking at the address of result in SASM's debug pane might have helped. But now that we've identified the problem using GDB, we can change your source to fix it for SASM.


You can use .globl result to make it an externally-visible symbol so it "wins" when the debugger is looking for symbols.

I added that and compiled again with gcc -g -no-pie store.s. It works as expected now, with p /x (unsigned long)result giving 0x404028

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847