Awkward data section behavior with NASM [duplicate

2019-01-15 11:34发布

问题:

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?

回答1:

At this moment, there doesn't seem to be much of a work around. This is a bug in 2.11.08, and I think some people have reported problems with 2.11.06 as well, so going to 2.11.05 is probably your best bet, or waiting for 2.11.09.