Autor Thema: .intel_syntax  (Gelesen 5287 mal)

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« am: 14. February 2012, 19:57 »
Hallo Leute,

ohne genug Erfahrung haben zu können und aus reiner eigener Präferenz würde
ich lieber die Intel-Syntax benützen als die AT&T.

Fürs erste hab ich Teil 4 des OS Tutorials gemacht und das funktioniert auch alles soweit.
Wenn ich aber die .intel_syntax Direktive verwende, dann funktioniert Hello World nicht mehr.

Funktioniert:
// ...
.global _start
    _start:
    mov $kernel_stack, %esp
    call init
// ...

Funktioniert nicht:
// ...
.global _start
    _start:
    .intel_syntax noprefix
    mov esp, kernel_stack
    call init
// ...

Kann mir da evenutell jemand verraten wie ich dem Assembler der korrekt beibringe?
Wäre super!

PS: Hallo übrigends Bin neu hier und heiße Stefan. Bin 24 aus Österreich/Kärnten und
studiere Informatik an der TU Graz. :)

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 14. February 2012, 21:11 »
Wenn ich aber die .intel_syntax Direktive verwende, dann funktioniert Hello World nicht mehr.
Funktioniert nicht? Dann hast du was falsch gemacht. ;)

Wenn du eine genauere Fehleranalyse haben willst als das, musst du genauer beschreiben, wie sich das Nichtfunktionieren denn genau äußert. In diesem Forum ist das leider so eine Unart, dass wir ständig unsere Kristallkugeln verlegen, sonst würden wir uns natürlich selbst drum kümmern, uns die Informationen zu beschaffen.

Also was ich jetzt gemacht habe, ist den Tutorialcode genommen (Commit dd51ecfc) und darauf folgenden Patch angewendet:
--- a/start.S
+++ b/start.S
@@ -19,8 +19,9 @@
 // sichtbar)
 .global _start
 _start:
+    .intel_syntax noprefix
     // Stack initialisieren
-    mov $kernel_stack, %esp
+    mov esp, kernel_stack

     // C-Code aufrufen
     call init

Das funktioniert bei mir einwandfrei. Aber AT&T-Syntax ist eh besser. ;)
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 15. February 2012, 11:24 »
Wenn du eine genauere Fehleranalyse haben willst als das, musst du genauer beschreiben, wie sich das Nichtfunktionieren denn genau äußert. In diesem Forum ist das leider so eine Unart, dass wir ständig unsere Kristallkugeln verlegen, sonst würden wir uns natürlich selbst drum kümmern, uns die Informationen zu beschaffen.

Jaaa das kenn ich, das passiert mir auch ständig ^^


Also was ich jetzt gemacht habe, ist den Tutorialcode genommen (Commit dd51ecfc) und darauf folgenden Patch angewendet:
--- a/start.S
+++ b/start.S
@@ -19,8 +19,9 @@
 // sichtbar)
 .global _start
 _start:
+    .intel_syntax noprefix
     // Stack initialisieren
-    mov $kernel_stack, %esp
+    mov esp, kernel_stack

     // C-Code aufrufen
     call init

Das funktioniert bei mir einwandfrei. Aber AT&T-Syntax ist eh besser. ;)

Wenn ich die Intel-Syntax verwende wird ganz einfach das Hello World nicht angezeigt.
Ein Bekannter meinte mit

mov esp, offset kernel_stack
würde es dann doch gehn. Tut es auch. Er meinte das wäre wegen GNU erforderlich.
Werde dann wohl mit NASM assemblieren ^^


Bevorzugst du AT&T aus rein ästhetischen Gründen oder hat das auch einen
praxisorientieren Hintergrund? :)

LG


kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 15. February 2012, 11:37 »
Wenn ich die Intel-Syntax verwende wird ganz einfach das Hello World nicht angezeigt.
Ein Bekannter meinte mit

mov esp, offset kernel_stack
würde es dann doch gehn. Tut es auch. Er meinte das wäre wegen GNU erforderlich.
Interessant. Wie gesagt hat es bei mir auch so funktioniert.

Wenn du den genauen Unterschied wissen willst, wäre es vielleicht interessant, beide Varianten mal zu bauen und dann zu disassemblieren (also mit objdump zu schauen, welche AT&T-Variante am Ende rauskommt).

Zitat
Werde dann wohl mit NASM assemblieren ^^

Bevorzugst du AT&T aus rein ästhetischen Gründen oder hat das auch einen
praxisorientieren Hintergrund? :)
Naja, AT&T ist die native Syntax von binutils, und auf andere Syntax umstellen hat mir bisher mit jedem Compiler/Assembler nur Probleme gebracht. Insofern ist deine Entscheidung, auf nasm umzustellen, vielleicht nicht so verkehrt. Ich bevorzuge halt inzwischen binutils/gas, weil das eh jeder installiert hat.
« Letzte Änderung: 15. February 2012, 11:39 von taljeth »
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 15. February 2012, 17:39 »
Also ich hab jetzt mal versucht das Tutorial mit NASM zu assemblieren..

section multiboot
MB_MODULEALIGN equ 0x0 ; not used
MB_MEMINFO equ 0x0 ; not used
MB_FLAGS equ MB_MODULEALIGN | MB_MEMINFO
MB_MAGIC equ 0x1BADB002
MB_CHECKSUM equ -(MB_MAGIC + MB_FLAGS)

dd MB_MAGIC
dd MB_FLAGS
dd MB_CHECKSUM

section .text

extern init

global _start
_start:
mov esp, kernel_stack
call init

_stop:
    cli
    hlt

    jmp _stop

section .bss
resb 8192 ; 8kB stack
kernel_stack:

Bezüglich der Syntax wird auch nicht gejammert, aber wenn ich den Kernel
boote mit qemu schreibt er mir kein Hello World raus.

Hab am Linkerskript nichts geändert, die ist noch 1:1 gleich wie hier,
nur die Makefile hab ich entsprechend verändert..

# ...
CC = gcc
AS = nasm
LD = ld

#ASFLAGS = -m32
ASFLAGS = -f elf
#...
%.o: %.S
$(AS) $^ $(ASFLAGS) -f elf -o $@
#$(CC) $(ASFLAGS) -c -o $@ $^
#...

Komm nicht dahinter.. der Multiboot-Header sollte so stimmen. Und auch das Linker-Skript
sollte das Objekt entsprechend aufbauen.
Nur bei $(AS) $^ $(ASFLAGS) -f elf -o $@ im Makefile bin ich mir nicht ganz sicher, aber es soll schon eine ELF sein oder?



*EDIT:
Okay, ich hab beim Multiboot-Header kein align angegeben.

;...
align 4
dd MB_MAGIC
dd MB_FLAGS
dd MB_CHECKSUM
;...
« Letzte Änderung: 15. February 2012, 21:47 von nnosdev »

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 17. February 2012, 17:51 »
Das mit dem offset hat folgendes auf sich:

Einige Assembler wie masm/tasm/gas halten sich leider für besonders schlau, indem sie neben Labels auch Variablen einführen. Das führt zu dem Problem, dass gas

mov esp, kernel_stack
genauso wie:
mov esp, [kernel_stack]
behandelt, wenn es kernel_stack als Variable auffasst, leider ist diese Funktion ziemlich unberechenbar.
Deshalb schrieb immer offset davor, wenn du die Addresse haben willst und kein + x oder so dar steht.

NASM hat das Problem erkannt und löst es, indem es grundsätzlich nur mit Labels arbeitet. Ohne Klammern ist in NASM also immer nur die Addresse.

 

Einloggen