Независимый код позиции, указывающий на неправильный адрес
У меня есть небольшой пример программы, написанной на 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 строки дБ (инициализированные данные), похоже, не работает. Там ОП подтвердила, что данные присутствовали, но метки были неправильными, и, мы надеемся, сообщит об этом ранее.