-
18. 01. 2012, 15:07 #1
[ASM] Intel Code to GCC Inline Assembler
Ich versuche seit über drei Stunden schon einen kurzen NASM Assembler Code
in eine C-Datei zu schreiben.
Kompilieren erledigt GCC.
%1 ist ein Word das ich als Parameter übergebe.Code:push ax push es xor ax, ax mov es, ax cli mov WORD [es:%1*4], %2 mov WORD [es:%1*4+2], cs sti pop es pop ex
%2 ist ein Pointer auf eine C Funktion die ich übergebe.
Beispiel:
set_ivt_entry(0x00,&handler);
Ich krieg das echt nicht hin.
Könnte mir jemand helfen?
Achja, wenn ich das übersetze lande ich immer bei einem Fehler
beim den beiden mov befehlen.
Immer was von invalid base/index oder junk "%%ex:2(0,%1,4)" oder so.
Was mach ich falsch???
Hoffe auf möglichst baldige Antwort
eyecikjou
-
18. 01. 2012, 22:51 #2Mitglied
- Registriert seit
- Apr 2011
- Beiträge
- 100
Re: [ASM] Intel Code to GCC Inline Assembler
Achtung gcc asm != nasm, was die Syntax angeht.
Ich glaube wenn ich an deiner Stelle wäre würde ich denn nasm Code in eine eigene Datei schrieben. und dann die beiden Objektfiles gegeneinander linken.
wie das geht kann man hier nachlesen.
http://www.nasm.us/doc/nasmdoc9.html
Generell glaube ich das es helfen könnte wenn du uns ein wenig mehr mit Infromationen versorgst zum beipiel dein Übergang von C nach ASM wäre sicher hilfreich, da meistens hier der Fehler liegt welcher dir nachher auf die Füsse fällt.
Außerdem bist du sicher das du in einen Assemblercode einen functionpointer übergeben willst das ist echt die hohe schule .
wenn handler ein function sein soll ist es sicher nicht &handler sonder wahrscheinlich eher nur handler.
-
19. 01. 2012, 16:32 #3
Re: [ASM] Intel Code to GCC Inline Assembler
Der Assembler unter GCC benutzt die AT&T Syntax. Diese unterscheidet sich sehr von der Intel Syntax.
Schau mal hier.
http://ibiblio.org/gferg/ldp/GCC-Inl...bly-HOWTO.html
sti und cli sind privilegierte Kommando, was hast Du denn vor?
http://en.wikipedia.org/wiki/Interrupt_flag
Sieht so aus als willst Du einen Interrupt Vektor manipulieren?
-
19. 01. 2012, 19:02 #4
Re: [ASM] Intel Code to GCC Inline Assembler
Infos:
Ja ich nutze sti und cli.
Es wird eine kleines OS.
Also immosieht es etwa soaus:
Aufrufender Code:Code:uint16_t *ivt_base = 0x0; uint16_t *ivt_seg = 0x0; void set_ivt_entry(uint16_t int_num, void *handler) { asm volatile ("cli"); uint16_t *int_num_seg0 = ivt_base + int_num * 4; uint16_t *int_num_dsp0 = ivt_base + int_num * 4 + 2; int_num_seg0 = ivt_base; int_num_dsp0 = handler; asm volatile ("sti"); } void init(void) { asm volatile ("cli"); asm volatile ("mov %%es, %1" : "=r"(ivt_seg)); asm volatile ("sti"); }
Das war was ich so ungefähr übersetz habe (ASM <-> C)Code:init(); set_ivt_entry(0x09,keyb); void keyb(void) { }
Allerdings bekomme ich immer einen Triple Fault nach ein paar Sekunden
(Virtual Box)
Was mach ich falsch??
(Oder wie würde der NASM Code in GAS Code aussehen so das ich es einfügen kann???)
edit:
Ich weiß das NASM != GAS/GCC
Ich will nicht die Objektfiles in die binary einfügen da:
1. Es wird ein OS. Also muss es unabhängig sein und der Assembler darf NIEMALS scheiß machen. bei inline Asm bin ich halt sicher das er es richtig übersetzt und einfügt.
2. ich will keine basteleien am Makefile
Das ich der Funktion set_ivt_entry einen FUnktionspointer übergebe ist absicht.
(Siehe unten)
Die IVT ist so aufgebaut:
0MB
+ INT 0x00
2byte SEGMENT
2byte OFFSET / DSP
+ INT 0x01
2byte SEGMENT
2byte OFFSET / DSP
+
...
bis 1 MB
d.h ich muss erst eine Position angeben (INTERRUPT_NUM * 4) an der ich ein Datenwort
abspeichern. Bei INTERRUPT_NUM * 4 + 2 wird das OFFSET (FUnktionspointer) abgespeichert (Theorie)
Link: http://www.lowlevel.eu/wiki/Interrupt_Vector_Table
Das setzen von IVT Einträgen ist meiner Meinung der Schritt der ein Program vom Betriebssystem unterscheidet (ich weiß da ist mehr :P ) deshalb will ich meinen KBC so schnell wie möglich fertig bringen und nächste Woche spätestens mit der Shell anfangen.
Danke für AufmerksamkeitGeändert von eye-ci-kjou (19. 01. 2012 um 20:19 Uhr)
-
20. 01. 2012, 16:19 #5
Re: [ASM] Intel Code to GCC Inline Assembler
Das alles spielt sich sicher im Real Mode ab. Da ist alles sehr einfach, im Gegensatz zum Protected Mode. Allerdings bist Du im Real Mode auch sehr eingeschränkt. Für den Anfang ist das aber ok. Achte darauf das Du für 16 Bit kompilieren musst.
Ok. pop ex gibt es nicht, Du meinst aber sicher pop axCode:push ax push es xor ax, ax mov es, ax cli mov WORD [es:%1*4], %2 mov WORD [es:%1*4+2], cs sti pop es pop ex
.
Das cs kann man nicht in einem mov kopieren. %1, %2 ist auch nicht korrekt, kann mir aber denken was Du meinst.
=> AT&T
Code:push %ax push %es xor %ax, %ax mov %ax, %es cli mov $2, %ax mov %ax, %es:($4) mov %cs, %ax mov %ax, %es:($6) sti pop %es pop %ax
Nicht unbedingt. Events in höheren Programmiersprachen ahmen sowas ganz gut nach. Natürlich werden die Interrupts direkt vom Prozessor unterstützt. Aber der Prozessor ist streng genommen eigentlich auch nur ein "Programm".Das setzen von IVT Einträgen ist meiner Meinung der Schritt der ein Program vom Betriebssystem unterscheidet (ich weiß da ist mehr :P ) deshalb will ich meinen KBC so schnell wie möglich fertig bringen und nächste Woche spätestens mit der Shell anfangen.
Viel Erfolg ich hoffe es hilft Dir weiter. Möglicherweise ist es aber doch besser den Bootloader komplett mit MASM oder NASM oder YASM und nicht in einer Hochsprache zu schreiben.Geändert von lupo1977 (20. 01. 2012 um 16:55 Uhr)
-
20. 01. 2012, 16:40 #6
Re: [ASM] Intel Code to GCC Inline Assembler
Mit %! und %2 meine ich parameter.
Also eigentlich %0 und %1 und später : "r"(int_num), "r"(handler)
des weiteren ist das eine Kopier einer FUNKTIONIERENDEN Funktion.
Also lässt sich cs kopieren.
Ich will doch nur das jemand das in ATT Syntax übersetzt
Naja vielen Dank für die Mühe
*grins*
Mein Problem liegt hauptsächlich bei den mov befehlen:
mov %ax, %es
$0,%0,4)
bzw
mov %ax, %es:2($0,%0,4)
Da kommt junk 2($0,%0,4) after expression
oder so
-
20. 01. 2012, 17:00 #7
Re: [ASM] Intel Code to GCC Inline Assembler
Parameter? In MASM ist das einfach falsch. Und Deine Frage war in MASM Syntax.
Was meinst Du mit Parametern? Das ist doch kein Template. GCC inline Assembly ist wirklich mächtig, aber...
Ich habe es nach AT&T übersetzt.
Wenn Du die Routine variabel willst wäre der beste Weg ein Indexregister si, di mit der Adresse zu übergeben und darüber zu referenzieren.
Zeig doch mal den Rest vom Code bitte.
Schau mal bitte hier nach den Operand Constraints.
http://ibiblio.org/gferg/ldp/GCC-Inl...bly-HOWTO.htmlGeändert von lupo1977 (20. 01. 2012 um 17:16 Uhr)
-
20. 01. 2012, 17:06 #8
Re: [ASM] Intel Code to GCC Inline Assembler
1. DAS IST NASM (siehe Link
)
2. Parameter => dem assembler makro ein par variable daten übergeben (siehe Post 1)
3. Da es ein INTEL Syntax ist muss du umgredreht denken. UND Ich kann Werte von ex in den Speicher kopieren.
-
20. 01. 2012, 17:10 #9
Re: [ASM] Intel Code to GCC Inline Assembler
Du stellst eine Frage zu AT&T postest aber INTEL Syntax. Warum zeigst Du nicht Deinen Versuch in AT&T?
Ich glaube Du gehst da falsch ran. Benutze lieber einen Assembler, dann wird es nicht so verwirrend
.
Was meinst Du mit ex in den Speicher kopieren?
EDIT:
Hmmm ok sehe gerade meinen Fehler.
Aber ehrlich gesagt gehst Du trotzdem falsch ran. Muss jetzt erst mal selber gucken wie man es machen könnte.Code:uint16_t *ivt_base = 0x0; uint16_t *ivt_seg = 0x0; void set_ivt_entry(uint16_t int_num, void *handler) { asm volatile ("cli"); uint16_t *int_num_seg0 = ivt_base + int_num * 4; uint16_t *int_num_dsp0 = ivt_base + int_num * 4 + 2; int_num_seg0 = ivt_base; int_num_dsp0 = handler; asm volatile ("sti"); } void init(void) { asm volatile ("cli"); asm volatile ("mov %%es, %1" : "=r"(ivt_seg)); asm volatile ("sti"); }
Ich würde an Deiner Stelle in diesem Fall auf inline Assembler verzichten.
EDIT2:
So kompiliert es bei mir. Scheint auch ok so zu sein.
Code:void set_ivt_entry(int int_num, void *handler) { asm( "push %%es;" "mov %0, %%si;" "add %%si, %%si;" "xor %%ax, %%ax;" "mov %%ax, %%es;" "mov %1, %%ax;" "add %%si, %%si;" "cli;" "mov %%ax, %%es:(%%si);" "mov %%cs, %%es:2(%%si);" "sti;" "pop %%es;" : : "g" (int_num), "g" (handler): "ax", "si"); }
Der Fehler rührt wohl daher weil es die komplexeren Adressierungsarten beim 8086 noch gar nicht gab.
Es handelt sich hier eben nicht um ein Makro sondern um inline Assembler. Ich vermute mal Du willst Assembler aus dem Weg gehen. Aber ehrlich gesagt wird das so echt schwer werden.2. Parameter => dem assembler makro ein par variable daten übergeben (siehe Post 1)Geändert von lupo1977 (20. 01. 2012 um 18:40 Uhr)
-
20. 01. 2012, 19:03 #10
Re: [ASM] Intel Code to GCC Inline Assembler
WOW Danke

Ich werts nacher gleich ausprobieren und schauen ob der IVT-Eintrag funktioniert
Ich meld mich dann nochmal
DD
-
21. 01. 2012, 02:29 #11
Re: [ASM] Intel Code to GCC Inline Assembler
Bitte beachte noch:
Das bedeutet das ISRs auch auf eine bestimmte Art beendet werden müssen. Eine einfache C Funktion erledigt diesen Job nicht für Dich.
Zitat von http://en.wikipedia.org/wiki/Interrupt_handler
-
21. 01. 2012, 14:19 #12
Re: [ASM] Intel Code to GCC Inline Assembler
normalerweise
werden ISRs über den befehle iret beendet.
ALso in C: "asm volatile ("iret");" ;D
-
21. 01. 2012, 15:32 #13
Re: [ASM] Intel Code to GCC Inline Assembler
Das ist korrekt. Aber in Deinem Beispiel oben hast Du das ignoriert. Naja, war vielleicht auch nicht vollständig. Sieht zumindest nicht so aus.
-


Zitieren

mehr lesen...







Resident Evil 6 erscheint in...
Heute, 15:21 in gulli:news