Проблема
Когда я компилирую свой ассемблерный код с as
(binutils) и связываю с помощью link.exe (Visual Studio 2015), программа вылетает из-за нерасположенного адреса.
Однако при компоновке с gcc (gcc hello-64-gas.obj -o hello-64-gas.exe
) программа работает правильно, без сбоев. Правильно ли я предполагаю, что объектный файл, сгенерированный as
, должен быть независимым от компилятора, поскольку проблемы совместимости с abi находятся в руках автора кода сборки? Поскольку я новичок, приветствуются любые объяснения моих ошибок / неверных предположений.
Платформа
- Windows 10, 64 бит
- Компоновщик: Visual Studio 2015 с использованием командной строки собственных командных инструментов (x64)
- Компилятор:
as
из MinGW-w64
Пример
Следующий код неверно связывает правильно:
# hello-64-gas.asm print a string using printf
# Assemble: as hello-64-gas.asm -o hello-64-gas.obj --64
# Link: link -subsystem:CONSOLE hello-64-gas.obj -out:hello-64-gas.exe libcmt.lib libvcruntime.lib libucrt.lib legacy_stdio_definitions.lib
.intel_syntax noprefix
.global main
# Declare needed C functions
.extern printf
.section .data
msg: .asciz "Hello world"
fmt: .asciz "%s(%d; %f)\n"
myDouble: .double 2.33, -1.0
.text
main:
sub rsp, 8*5
mov rcx, offset flat: fmt
mov rdx, offset flat: msg
mov r8, 0xFF
mov r9, offset flat: myDouble
mov r9, [r9]
movq xmm4, r9
call printf
add rsp, 8*5
mov rax, 0
ret
При отладке кажется, что mov r9, offset flat: myDouble
не перемещается: mov r9,18h
, где 18h
было бы правильным, если бы раздел .data
находился в нулевой позиции. Если посмотреть на таблицу перемещений с objdump -dr hello-64-gas.obj
доходностью:
...
19: 49 c7 c1 18 00 00 00 mov $0x18,%r9
1c: R_X86_64_32S .data
...
Вариант (обходной путь?)
Замена mov
на movabs
вроде работает:
# hello-64-gas.asm print a string using printf
# Assemble: as hello-64-gas.asm -o hello-64-gas.obj --64
# Link: link -subsystem:CONSOLE hello-64-gas.obj -out:hello-64-gas.exe libcmt.lib libvcruntime.lib libucrt.lib legacy_stdio_definitions.lib
.intel_syntax noprefix
.global main
# Declare needed C functions
.extern printf
.section .data
msg: .asciz "Hello world"
fmt: .asciz "%s(%d; %f)\n"
myDouble: .double 2.33, -1.0
.text
main:
sub rsp, 8*5
movabs rcx, offset flat: fmt
movabs rdx, offset flat: msg
mov r8, 0xFF
movabs r9, offset flat: myDouble
mov r9, [r9]
movq xmm4, r9
call printf
add rsp, 8*5
mov rax, 0
ret
Это каким-то образом работает правильно при связывании с использованием link.exe
.