This question already has an answer here:
- NASM compiling x86_64 ASM label addresses off by 256 bytes in Mach-O when using multiple db declarations? 2 answers
I am writing some basic programs in assembly, in which I simply make some function calls. I am on OS X, using the Mach-O 64 bit format. However, there seems to be a flaw in my understanding of the data section. I understand that the data section is intended to be used for initialized data, and I have decided to initialize two blocks of memory, as shown below:
default rel
global _main
extern _puts
section .data
first db "Message A", 0 ; null terminator
second db "Message B", 0
section .text
_main:
push rbp ; alignment
mov rbp, rsp
sub rsp, 0x10
lea rdi, [second]
call _puts
lea rdi, [first]
call _puts
add rsp, 0x10
pop rbp
ret
(I am linking against libc, obviously)
My understanding is that the stack must be 16 byte aligned according to the System V ABI specification. Additionally, rdi should contain the first argument to the function call.
The above code will print "Message B", but fail to print "Message A" directly after. It's as if "Message A" was overwritten somewhere.
What is also very interesting is that when I enter the two strings in the .text
section, the code works as intended. Since .text
is read-only, I am almost certain that the "Message A" is being overwritten sometime after initialization. No matter how many strings I enter in the .data
section, I can only ever print the last one, and the other ones are simply overwritten. Why is the last string initialized the only one that is not overwritten?