Wie finde ich eine Variable in der AT&T-Assembly richtig?
-
11-12-2019 - |
Frage
Ich übe, einen Bootstrap mit Assembler zu schreiben (in AT&T-Syntax und GNU/Gas).Das kleine Programm wird zusammengestellt und verknüpft und dann in den ersten Sektor einer virtuellen Festplatte kopiert.Das BIOS wird es laden 0000:7c00
, und hier kommt das Problem.Der call hello
wird übersetzt von call 0010
Zu call 7c10
beim Laufen.Aber die movw $message, %as
wird nicht verlegt.Der ax
ist immer noch 0026
, nicht 7c26
.Das Ergebnis ist, dass ich das nicht schaffen kann Hello World
auf dem Bildschirm.Stattdessen einige zufällige Daten bei 0000:0026
wird auf dem Bildschirm angezeigt.
Wie kann ich es beim Booten korrigieren?Sollte ich den ASM-Quellcode mithilfe einiger Anweisungen ändern?Oder sollte ich mein Linkskript ändern?
Danke schön!
.text
.global _start
.code16
_start:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
call hello
jmp .
.org 0x10
hello:
movw $message, %ax
movw %ax, %bp
movw $13, %cx
movw $0x1301, %ax
movw $0x000c, %bx
movb $0, %dl
int $0x10
ret
message:
.ascii "Hello, World!"
.org 0x01fe
.byte 0x55
.byte 0xaa
Ich verwende die folgenden Assemble- und Link-Skripte
as -o boot.o boot.s
//generate object code
ld -Ttext 0x0 -e _start -s -o boot.out boot.o
//relocate .text to 0x0
//entry is _start
objcopy -O binary -j .text boot.out boot
//copy .text section to boot
vboxmanage convertfromraw boot boot.vdi --format VDI
//create vdi for virtual box
Lösung
Ich sehe, dass das Hauptproblem in der Art und Weise liegt, wie Sie Ihren Code kompilieren.
Die richtigen Schritte, um Ihren Code zum Laufen zu bringen, sollten sein:
as boot.s -c -o boot.o
ld --oformat binary --Ttext 0x7C00 -o boot.bin boot.o
Bitte beachten Sie, wie andere bereits gesagt haben, dass ich das übergebe --Ttext 0x7C00
Parameter zu ld
, um die Verschiebung Ihres Codes an dieser Adresse zu erzwingen.
Versuchen Sie als zusätzlichen Vorschlag, Ihren Code wie folgt zu strukturieren:
.text
.global _start
.code16
_start:
jmp stage1_start
...
stage1_start:
<your bootloader here>
Beachten Sie, dass dies mit der Art und Weise übereinstimmt, wie der BIOS-Code auf Festplatten aussieht, da Sie nach 2 Bytes (der Länge des ersten Sprungbefehls) die Festplattenbeschreibungstabelle platzieren sollten.
Darüber hinaus können Sie Ihre letzten Anweisungen in mehr umgestalten as
-ähnliche Syntax wie diese:
. = _start + 0x0200 - 2
.short 0x0AA55
Bei dem die .
Variable ist der Standortzähler.Ansehen diese Seite Weitere Informationen zur Funktionsweise dieses Zählers finden Sie im Kontext von ld
, nicht as
).
Hoffe das hilft!