Initialized static data you want to modify at runtime goes in .data
, not .text
.
The .text
section is mapped read+exec, .data
is mapped read+write.
Compilers use .section .rodata
for read-only static data, to group data separately from code. That sections is linked as part of the text segment.
If you want to put a 64-bit address in a register, you should use lea hello_world(%rip), %rdi
But if that was the problem (truncating the address to a 32-bit immediate from movq
instead of movabs
), you'd get a linker error.
So clearly you're linking this into a non-PIE executable on Linux (because you used printf
not _printf
(so it's not OS X where movq $symbol, %r64
will use a 64-bit absolute immediate), and didn't get link errors from using 32-bit absolute relocations for symbol addresses. Difference between movq and movabsq in x86-64
(On Linux, static addresses in position-dependent executables using the default code model fit in 32 bits.)
You can simplify your program to this, for a Linux non-PIE executable:
.data # mutable static data
hello_world: .asciz "hellothere \n"
#.section .rodata # read-only static data
.text # code
.global main
main:
mov $hello_world, %edi # most efficient way to put a static addr in a reg
# in a position-dependent executable
xor %eax,%eax # most efficient way to zero the whole 64-bit reg
call printf
mov $hello_world, %edi
movb $'a', (%rdi) # store directly to memory instead of using a partial register
xor %eax,%eax
call printf
xor %eax,%eax # return 0, otherwise you might as well jmp printf
ret # might as well just ret instead of calling exit since this is main, not _start
compiles and runs correctly with gcc -no-pie hello-mutable.S && ./a.out
, or fails to link with gcc -pie
.
To build with -pie
(the default on many modern distros), use lea hello_world(%rip), %rdi
both times.
Of course you could also use puts
instead of printf
because your format string has no %
chars in it. (Just remove the trailing \n
.) Compilers do this optimization when compiling C. It's more efficient, and you wouldn't need to zero AL.