2015-07-26 8 views
2

У меня есть небольшая примерная программа, написанная в 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 - это единственное сообщение, которое печатается.

+0

Резолюция здесь оказалась темной. Я вряд ли могу сказать, что nasm работает некорректно, но после смены на ярость все шло так, как ожидалось. – ryanday

ответ

1

ИДК о Маха-о ABI, но если это то же самое, как x86-64 SystemV использует ABI GNU/Linux, то я думаю, ваша проблема в том, что вам нужно очистить eax сказать функцию с переменным числом аргументов, как printf что равны нулю FP.

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

Похоже, у NASM есть ошибка. Эта же проблема снова возникла: NASM 2 lines of db (initialized data) seemingly not working. Там OP подтвердил, что данные присутствовали, но метки были неправильными и, надеюсь, сообщают об этом выше по течению.

+0

Хорошо поймать на регистрах. Я обновился до rdi, и я очищаю rax (пример кода обновлен). У меня все еще такая же проблема, но код лучше. – ryanday

+0

Обычная идиома - 'xor eax, eax'. Это один байт короче. Запись в 32-битный регистр всегда очищает верхнюю часть 32. Что выводит компилятор для функции C, которая вызывает 'printf', дважды на вашей платформе? Компиляция с оптимизацией, так что вы не получите кучу избыточных нагрузок/хранилищ. –

+0

Кроме того, в gdb вы можете проверить значения регистра перед вызовом и убедиться, что содержимое памяти по этому адресу является 'msg1'. gdb для инструкций asm по адресу http://stackoverflow.com/tags/x86/info –

 Смежные вопросы

  • Нет связанных вопросов^_^