8 Stimmen

Wie man eine Assembler-Datei mit dem GNU Assembler (as) in ein Rohdatenformat (wie DOS .com) kompiliert?

Ich möchte diesen Quellcode in Windows kompilieren (es ist nur ein Beispiel):

start:
NOP
NOP

Wenn ich es mit NASM oder FASM kompiliere, beträgt die Länge der Ausgabedatei 2 Bytes. Aber wenn ich es mit dem GNU Assembler (as) kompiliere, beträgt die Länge der Ausgabedatei 292 Bytes!

Wie kompiliere ich eine Assemblierdatei im Rohbinary-Format (wie DOS .com) mit dem GNU Assembler (as)?


Warum mache ich das?

Ich möchte mein eigenes einfaches Betriebssystem schreiben, ich schreibe meinen Code mit C (ohne Verwendung von C-Standardbibliotheken wie stdio.h oder math.h) und konvertiere ihn in Assembler:

gcc -S my_os.c -o my_os.asm -masm=intel

Dann kompiliere ich die Assemblierdatei in ein Rohbinary:

as my_os.asm

Dann benenne ich a.out (Ausgabe des Assemblers) in my_os.flp um und starte schließlich mein Betriebssystem mit VMWare :)

1 Stimmen

Vielleicht können Sie damit beginnen, Ihren eigenen Assembler zu schreiben :) Ich vermute, dass die "290" Bytes, auf die Sie sich beziehen, aus dem Dateikopf stammen: Jede binäre Objektdatei hat einen davon.

0 Stimmen

@paulsm4: Ja! 290 Bytes Header, aber ich möchte keine Kopfzeile!

0 Stimmen

@Amir - kannst du nicht einfach objcopy oder segedit verwenden, um die Binärteile zu kopieren, die dir wichtig sind?

7voto

ld --oformat binary

Für schnelle und schmutzige Tests können Sie folgendes tun:

as -o a.o a.S
ld --oformat binary -o a.out a.o
hd a.out

Gibt:

00000000  90 90                                             |..|
00000002

Leider wird eine Warnung ausgegeben:

ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000

was mit binary nicht viel Sinn ergibt. Es könnte mit folgendem unterdrückt werden:

.section .text
.globl start
start:
nop
nop

und:

ld -e start --oformat binary -o a.out a.o

oder einfach mit:

ld -e 0 --oformat binary -o a.out a.o

was ld sagt, dass der Einstiegspunkt nicht _start ist, sondern der Code an Adresse 0.

Es ist schade, dass weder as noch ld Eingabe / Ausgabe von stdin / stdout akzeptieren können, also kein Piping.

Richtiger Bootsektor

Wenn Sie etwas ernsthafteres tun möchten, ist die beste Methode, ein sauberes minimales Linkerskript zu generieren. linker.ld:

SECTIONS
{
    . = 0x7c00;
    .text :
    {
        *(.*)
        . = 0x1FE;
        SHORT(0xAA55)
    }
}

Hier platzieren wir auch die magischen Bytes mit dem Linkerskript.

Das Linkerskript ist vor allem wichtig, um die Ausgabeadressen nach der Relokation zu kontrollieren. Erfahren Sie mehr über Relokation unter: https://stackoverflow.com/a/30507725/895245

Verwenden Sie es wie folgt:

as -o a.o a.S
ld --oformat binary -o a.img -T linker.ld a.o

Und dann können Sie wie folgt booten:

qemu-system-i386 -hda a.img

Funktionierende Beispiele in diesem Repository: https://github.com/cirosantilli/x86-bare-metal-examples/blob/d217b180be4220a0b4a453f31275d38e697a99e0/Makefile

Getestet mit Binutils 2.24, Ubuntu 14.04.

0voto

Alexey Frunze Punkte 59460

Verwenden Sie NASM mit der Option -f bin, um Ihren Assemblercode in eine reine Binärdatei zu kompilieren.

0 Stimmen

Aber NASM kann den Assembly-Ausgang von gcc nicht kompilieren (Siehe gcc -S my_os.c -o my_os.asm -masm=intel)

5 Stimmen

Auf der anderen Seite erzeugt gcc keinen 16-Bit-Code, den Sie benötigen, da Ihr Bootsektor im 16-Bit-Modus ausgeführt wird. Alle Zeiger-/Adressmanipulationen im für den 32-Bit-Modus kompilierten C-Code sind im 16-Bit-Modus falsch.

1 Stimmen

Downvoter, sei konstruktiver.

0voto

sarkiroka Punkte 1380
org 100h
nop
nop

Sie können fasm zum Kompilieren verwenden:

fasm yourcode.asm targetfilename.com

0 Stimmen

Die Frage sagt bereits "Wenn ich es mit NASM oder FASM kompiliere, ist die Ausgabedateilänge 2 Bytes". Dies ist keine Antwort auf diese Frage, die sich um GAS handelt.

0 Stimmen

Ich verstehe, aber ich verstehe nicht, warum ein anderer Compiler verwendet werden muss, wenn fasm das richtige Ergebnis produziert.

0 Stimmen

Dies wurde bereits in den Kommentaren diskutiert unter der Antwort nasm -f bin (die dieselbe Antwort wie diese ist). Vermutlich möchten sie aus irgendeinem Grund die GAS-Syntax verwenden, nicht NASM oder FASM. Oder es scheint, dass die Frage aus dem falschen Eindruck stammt, dass man dies mit der Ausgabe von gcc -S nützlich für die Erstellung von 16-Bit-Code verwenden könnte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X