nasm / ld "Umzug abgeschnitten, um zu passen: R_386_16"

Versammlung

[BITS 16]

global _start

_start:
    mov ax, 0x07C0
    mov ds, ax

    mov si, hw
    call print_string
    jmp $

print_string:
    mov ah, 0x0E
.char:
    lodsb
    cmp al, 0
    je .exit
    int 0x10
    jmp .char
.exit: ret

times 0x100-($-$) db 0

hw: db "Hello, World!", 0

times 510-($-$) db 0
dw 0xAA55

Montage mit:

$ nasm file.asm -felf -o file.o

Und verknüpfe es dann mit:

$ ld -melf_i386 -o file.bin file.o --oformat binary

Gibt den folgenden Fehler:

file.asm:(.text+0x6): relocation truncated to fit: R_386_16 against `.text'

Nachdem ich ein bisschen mit dem Code herumgespielt habe, habe ich herausgefunden, dass sichmov si, hw zumov si, 0x100 funktioniert gut. Aber worum geht es dann bei Etiketten?

Meine Vermutung ist, dass ld keine 16-Bit-Binärdateien generieren kann, also ersetzt eshw mit einer 32-Bit-Adresse anstelle einer 16-Bit-Adresse. Und dann beschwert es sich, weil mein Programm versucht, einen 32-Bit-Wert in ein 16-Bit-Register zu schreiben.

Gibt es ein Argument, das ich an nasm / ld übergeben kann, damit das funktioniert?

BEARBEITEN

elf unterstützt kein 16-Bit-Format, das einzige von nasm unterstützte Ausgabeformat, in dem angegeben wird, dass es 16-Bit in @ unterstütznasm -hf ist .obj, aber ich kann keinen Linker dafür finden.

NASM Manual:

Die ELF32-Spezifikation sieht keine Verschiebungen für 8- und 16-Bit-Werte vor, aber der GNU ld-Linker fügt diese als Erweiterung hinzu. NASM kann GNU-kompatible Verschiebungen generieren, damit 16-Bit-Code mit GNU ld als ELF verknüpft werden kann. Wenn NASM mit der Option -w + gnu-elf-extensions verwendet wird, wird eine Warnung ausgegeben, wenn eine dieser Verschiebungen generiert wird.

Adding-w+gnu-elf-extensions zeigt zwar eine Warnung an, aber ld gibt immer noch den gleichen Fehler aus.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage