/ / Dlaczego użycie jmp uniemożliwia asemblerowi Clanga wymyślenie absolutnego wyrażenia dla .fill? - macos, asembler, x86, clang, bootloader

Dlaczego użycie jmp uniemożliwia asemblerowi Clang wykrycie bezwzględnego wyrażenia dla .fill? - macos, assembly, x86, clang, bootloader

Nie radzę sobie z pisaniem prostego modułu ładującego (dodatkowe informacje na dole posta) nasm kod pokazuje, jak wyglądał bootloader w pewnym momencie, zanim spróbowałem przełączyć się na Clang. Po kompilacji za pomocą nasm -f bin -o nasm.out boot.asm, a następnie uruchom za pomocą qemu-system-i386 nasm.out, drukuje niekończący się strumień ! znaki na ekranie:

bits 16
global main
main:
mov ah, 0x0e
mov al, "!"
int 0x10
jmp main
times 510 - ($ - $$) db 0x00
db 0x55
db 0xaa

Byłem ciekawy, czy mógłbym użyć Clanga jako mojego asemblera zamiast nasm, więc spróbowałem przetłumaczyć program na, jak myślę, odpowiednik składni GAS:

.code16
.global main
main:
mov $0x0e, %ah
mov $"!", %al
int $0x10
jmp main
.fill 510 - (. - main)
.byte 0x55
.byte 0xaa

Jednak po skompilowaniu przy użyciu /usr/local/opt/llvm/bin/clang --target=i386-elf -m16 -c boot.s -o boot.o, Pojawia się następujący błąd:

boot.s:9:7: error: expected absolute expression
.fill 510 - (. - main)
^

Kompilacja się powiedzie, jeśli jmp main zastępuje się jmp *0x00 lub niejmp instrukcja. Nie jest to ściśle równoważne, ale wydaje się wskazywać na coś w etykiecie, która daje problemy Clangowi.

nasm nie miałem żadnych problemów z określeniem, ile bajtów użyć do wypełnienia. Dlaczego Clang nie chce, gdy poproszę o to samo?

Zawsze mogę ręcznie ustalić, ile bajtów wypełnienia potrzebuję, ale jest to żmudne i podatne na błędy i wydaje się, że asembler powinien być w stanie zrobić to sam.

Używam Clang 4.0, zainstalowanego przez Homebrew, na macOS 10.12.6.


  • Szybkie odświeżanie bootloadera, jeśli go potrzebujesz: sektor rozruchowy ma 512 bajtów długości i musi mieć wartości 0x55 i 0xaa przy przesunięciach odpowiednio 510 i 511. Łatwym sposobem zapewnienia tego jest upewnienie się, że wyjście binarne ma dokładnie 512 bajtów i ma 0x55 i 0xaa jako ostatnie dwa bajty.

Odpowiedzi:

0 dla odpowiedzi № 1

Clang ma własny asembler, który nie rozumie całej składni asemblera GNU. Zamiast tego spróbuj asemblera za pomocą asemblera GNU, tzn. Używając as --32 -o boot.o boot.s, to powinno działać.