Независимый код позиции, указывающий на неправильный адрес

У меня есть небольшой пример программы, написанной на NASM(2.11.08), предназначенной для архитектуры macho64. Я использую OSX 10.10.3:

bits 64

section .data

    msg1    db 'Message One', 10, 0
    msg1len equ $-msg1
    msg2    db 'Message Two', 10, 0
    msg2len equ $-msg2

section .text
    global  _main
    extern  _printf

_main:
    sub     rsp, 8  ; align

    lea     rdi, [rel msg1]
    xor     rax, rax
    call    _printf

    lea     rdi, [rel msg2]
    xor     rax, rax
    call    _printf

    add rsp, 8
    ret

Я компилирую и компоновку, используя следующую командную строку:

/usr/local/bin/nasm -f macho64 test2.s
ld -macosx_version_min 10.10.0 -lSystem -o test2 test2.o

Когда я делаю объектный дамп в исполняемом файле test2, это соответствующий фрагмент (я могу опубликовать больше, если я ошибаюсь!):

0000000000001fb7 <_main>:
1fb7:   48 83 ec 08             sub    $0x8,%rsp
1fbb:   48 8d 3d 56 01 00 00    lea    0x156(%rip),%rdi        # 2118 <msg2+0xf3>
1fc2:   48 31 c0                xor    %rax,%rax
1fc5:   e8 14 00 00 00          callq  1fde <_printf$stub>
1fca:   48 8d 3d 54 00 00 00    lea    0x54(%rip),%rdi        # 2025 <msg2>
1fd1:   48 31 c0                xor    %rax,%rax
1fd4:   e8 05 00 00 00          callq  1fde <_printf$stub>
1fd9:   48 83 c4 08             add    $0x8,%rsp
1fdd:   c3                      retq  

...

0000000000002018 <msg1>:
0000000000002025 <msg2>:

И, наконец, вывод:

$ ./test2
Message Two
$

У меня вопрос, что случилось с MSG1?

Я предполагаю, что MSG1 не печатается, потому что 0x14f(%rip) не правильный адрес (просто нули).

Почему lea edi, [rel msg2] указывая на правильный адрес, в то время как lea edi, [rel msg1] указывает за msg2, в NULL?

Похоже, 0x14f(%rip) Смещение точно равно 0x100 за пределы, где msg1 лежит в памяти (это верно во многих тестах этой проблемы).

Что мне здесь не хватает?

Редактировать: какое бы сообщение (msg1 или msg2) не появилось последним в разделе.data, это единственное сообщение, которое печатается.

1 ответ

Решение

IDK о Mach-o ABI, но если он такой же, как в SystemV x86-64 ABI GNU/Linux, то я думаю, что ваша проблема в том, что вам нужно очистить eax чтобы сказать функцию Varargs, как printf что есть ноль FP.

Также, lea rdi, [rel msg1] будет намного лучшим выбором. В своем нынешнем виде ваш код не зависит от позиции только в пределах 32 бит виртуального адресного пространства, потому что вы усекаете указатели до 32 бит.

Похоже, что в NASM есть ошибка. Эта же проблема возникла снова: NASM 2 строки дБ (инициализированные данные), похоже, не работает. Там ОП подтвердила, что данные присутствовали, но метки были неправильными, и, мы надеемся, сообщит об этом ранее.

Другие вопросы по тегам