Próbuję wykonać odpowiedź na this thread, która niestety nie do końca rozwiązuje mój problem. Kod próbuję uruchomić to w następujący sposób:X86 64-bitowy montaż Linux "Hello World" linkujący numer
; File hello.asm
section .data
msg: db "Hello World!",0x0a,0
section .text
global main
extern printf
main:
push rbp
mov rbp, rsp
lea rdi, [msg] ; parameter 1 for printf
xor eax, eax ; 0 floating point parameter
call printf
xor eax, eax ; returns 0
pop rbp
ret
Mój system to debian odcinek:
$ uname -a
Linux <host> 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux
Używam yasm
asembler następująco:
$ yasm -f elf64 -g dwarf2 hello.asm
Ponieważ mój wpis punkt w powyższym źródle to main
z ostateczną instrukcją ret
, zgaduję, że muszę połączyć się z gcc
zamiast ld -e main
:
$ gcc -lc hello.o
jednak otrzymuję następujący komunikat o błędzie:
/usr/bin/ld: hello.o: relocation R_X86_64_32 against `.data' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
Ten błąd wspomina coś o rekompilacji z -fPIC
ale jest to ważna opcja w asemblerze yasm
opcja gcc
kompilator nie . Więc nie wiem, co robić tutaj.
Właśnie przez wzgląd na testach, starałem się połączyć z ld
:
$ ld -e main -lc hello.o
co jest skuteczne, ale uzyskać ten sam błąd, o którym mowa w powyższym wątku, gdy uruchomiony:
$ ./a.out
bash: ./a.out: No such file or directory # The file *is* there ...
(po odpowiedzi na wątek, próbowałem porównać bibliotekę .so
wspomnianą w pliku binarnym ld
z biblioteką mojego systemu i oba są /lib64/ld-linux-x86-64.so.2
.)
Próbowałem również zastąpić punkt wejścia main
za pomocą _start
(zapomniałem o problemie wyjścia z programu na razie) i połączyć z ld -lc hello.o
, ale pojawia się ten sam błąd "Brak takiego pliku lub katalogu" jak wcześniej. Nadal będę się z tym bawił, ale myślałem, że też zapytam.
Każda sugestia pracy (z main
lub _start
, gcc
lub ld
) zostanie docenione ciepło.
EDIT: Jak sugeruje Jim Dodałem default rel
na szczycie hello.asm
i uzyskać inny komunikat o błędzie podczas łączenia z gcc (bez zmian ze ld -e main -lc
)
$ gcc -lc hello.o
/usr/bin/ld: hello.o: relocation R_X86_64_PC32 against symbol `[email protected]@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
EDIT2: Ten post odnosi się do niepowodzenia: debian stretch
:
Linux: 4.8.0-1-amd64 #1 SMP Debian 4.8.7-1 (2016-11-13) x86_64 GNU/Linux
yasm: 1.3.0
gcc: (Debian 6.2.1-5) 6.2.1 20161124
ld: GNU ld (GNU Binutils for Debian) 2.27.51.20161220
Następna ng na komentarzem Jima właśnie testowane ten sam kod nadebian jessie
który działa perfekcyjnie z gcc -lc hello.o
i następujących wersjach:
Linux: 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
yasm: 1.2.0
gcc: (Debian 4.9.2-10) 4.9.2
ld: GNU ld (GNU Binutils for Debian) 2.25
EDIT 3: W oczekiwaniu na formalną odpowiedź od Michaela Petch: problem rozwiązany zgcc -static hello.o
Twój kod faktycznie działa dla mnie (w innej dystrybucji). Twój problem wydaje się być związany z typem relokacji 'hello.o'. Sugerowałbym dodanie dyrektywy 'default rel' do początku' hello.asm' i zobaczenie, czy to działa lub daje inny błąd. Czy celowo używasz przeniesienia R_X86_64_32? –
@ Jimd. bardzo ci dziękuje za pomoc. Zmodyfikowałem mój post, aby wskazać nowy komunikat o błędzie. –
Co się stanie, jeśli kompilujesz statycznie za pomocą 'gcc -static hello.o' –