paule22 Geschrieben 26. April 2009 Teilen Geschrieben 26. April 2009 Hallo Miteinander! Ich bin gerade dabei einen Compiler zu schreiben. Wie kann ich den Ausdruck: ident '=' expr (Zeile: 218) also: variable = 12 in Assembler umsetzen? Als Grundlage soll folgender Yacc Source dienen: nopaste.info - free nopaste script and service Für Anregungen und Informationen bin ich jedem dankbar. MfG paule22 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 26. April 2009 Teilen Geschrieben 26. April 2009 Vielleicht habe ich nicht richtig verstanden, was Sie genau erfahren möchten. variable = 12 asm: mov [variable],12 ; Intel syntax movl $12,$variable ; AT&T syntax Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 26. April 2009 Autor Teilen Geschrieben 26. April 2009 Hallo, wie man ein Assemblerprogramm schreiben kann, ist für mich noch etwas neuland. Kann aber schon Konstrukte aufstellen. unter nopaste.info - free nopaste script and service könnt Ihr eine etwas überarbeitete Version vorfinden. Was mir komisch vorkommt ist, das Stack nicht gleich Stack ist. Zum Beispiel beginnend ab Zeile 256 hochrangelnd auf Zeile 216 -> expr (Zeile 88) -> weiter bei Zeile 118. Warum wird dann folgender Code erzeugt: Für Ideen und Vorschläge bin ich jedem dankbar! Gruß Jens --- BITS 32 cpu 486 extern _exit, _show_message extern _set_vergleichswert_A1 extern _set_vergleichswert_A2 extern _set_vergleichswert_byvar extern _vergleiche_cmpeq @var_var1: dd 10 @Pshow_message0: db "ist 5",0 @Pshow_message1: db "juhu 5",0 @Pshow_message2: db "nuja halt 7",0 @Pshow_message3: db "ok",0 @Pshow_message4: db "ist nicht 5",0 segment .text global _start_main _start_main: push ebp mov ebp, esp ; die folgende Zeilen müssten doch theoretisch ; unter push [@var_var2] stehen? ; mache ich einen Programmierfehler oder liegt ; das Problem am Yacc? call _set_vergleichswert_byvar add esp, 8 push dword [@var_var1] push dword [@var_var2] call _vergleiche_cmpeq cmp eax, 1 jne near Le0 push @Pshow_message0 call _show_message jmp near Lj0 Le0: call _vergleiche_cmpeq cmp eax, 1 jne near Le2 push @Pshow_message1 call _show_message jMP near Lj2 Le2: call _vergleiche_cmpeq cmp eax, 1 jne near Le4 push @Pshow_message2 call _show_message push @Pshow_message3 call _show_message jMP near Lj4 Le4: push @Pshow_message4 call _show_message jmp near Lj4 Lj4: jmp near Lj2 Lj2: jmp near Lj0 Lj0: push dword 0 call _exit leave ret --- der QuellCode schaut wie folgt aus: ... var1 = 10 //var2 = 1 if var1 = var2 showmessage("ist 5") elseif 5 = 7 showmessage("juhu 5") elseif 5 = 5 showmessage("nuja halt 7") showmessage("ok") else showmessage("ist nicht 5") endif ... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 26. April 2009 Teilen Geschrieben 26. April 2009 Ich möchte gern procedure "_vergleiche_cmpeq" und "_set_vergleichswert_byvar" in ASM sehen. Dann kann man sagen,warum das Stack nicht gleich Stack ist. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 26. April 2009 Teilen Geschrieben 26. April 2009 call _set_vergleichswert_byvar add esp, 8 Wenn es C-call ist, dann braucht man zwei PUSHs bevor. push dword [@var_var1] push dword [@var_var2] call _vergleiche_cmpeq Procedure _vergleiche_cmpeq hat zwei Args. Oder? Warum gibt es keine Args: Le0: call _vergleiche_cmpeq Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 27. April 2009 Autor Teilen Geschrieben 27. April 2009 Hallo Perfiliev, vielleicht sollte ich etwas zu dem Projekt sagen ... Es handelt sich hierbei wohl eher um einen Skript-Compiler. Das hört sich jetzt vielleicht lustig an, ist aber so :-) Der Kern des Compilers wurde von mir in Delphi 7 gestartet/programmiert. Mittlerweile wird das Projekt unter Windows Vista und CodeGear (Delphi 2009) weiter entwickelt, da es zu Problemen mit Delphi 7 unter Vista (Kompatibilität) gab. Unter dem WebLink: TP Lex/Yacc kann man die tply41a.zip downloaden (Yacc für Pascal) So als Grundlage für den Compiler dient der nopaste code vom letztem Posting. Yacc ist ja Stack basierend, vielleicht hier die kleine Unmissverständlichkeit. Der ParserCode erzeugt aus einer Quelldatei NASM (Netwide Assembler) Win32 Code. NASM verwende ich dann um den ASM-Text/Ausgabe in Win32 obj binary umzuwandeln. Dieser obj Code ist kompatibel mit den MingW32 GCC Compiler. Deshalb auch meine Wahl des Assemblers. Mittels selbst geschriebener Lib's (ausser Qt 4.3.4) werden dann die Daten gegeneinander zu einer EXE Datei gelinkt. Eine BATCH Datei würde dann so aussehen: set path=i:\mingw\bin;i:\qt\4.3.4\bin;%path% nasm -f win32 11.asm g++ -o 11.exe 11.obj -Li:\Qt\4.3.4\lib -L.\lib -lkalib -lkagraph -lxbase -lkernel32 -lwin32k -lQtCore4 -lqtmain -lQtGui4 Nun zu den cmp Funktionen: Dazu dient ein Ausschnitt aus der Datei jk_class.cc: ... float ErgebnisWert = 0.0; float vglwertA1 = 0; float vglwertA2 = 0; extern "C" void set_vergleichswert_A1(int nach, int vor) { vglwertA1 = QString("%1.%2").arg(vor).arg(nach).toFloat(); } extern "C" void set_vergleichswert_A2(int nach, int vor) { vglwertA2 = QString("%1.%2").arg(vor).arg(nach).toFloat(); } // die folgende Funktion muss noch angepasst werden // Sie steht nur exemplarisch (erstmal) hier aufgelistet ... extern "C" void set_vergleichswert_byvar(float v1, float v2) { vglwertA1 = v1; vglwertA2 = v2; } extern "C" int vergleiche_cmpeq(void) { if (vglwertA1 == vglwertA2) return 1; else return 0; } ... Zu Deiner Frage mit (siehe obigen Code _exemplarisch_), Wenn es C-call ist, dann braucht man zwei PUSHs bevor. ja das ist richtig, aber das ist das wenigste Problem (erstmal). _vergleiche_cmpeq hat wie im Code oben zu sehen ist kein Argument. Zu den CodeAbschnitt Je0: call _vergleiche_cmpeq hier handelt es sich um eine NichtOptimierter Codestelle. Es wird halt nochmals auf "=" (Gleichheit) geprüft - der Compiler in seiner jetzigen Form ist halt noch ein recht dummy/dummer Automat, der keinen optimierten Code auswirft. So das dazu erstmal. Nun zum eigentlichem Problem: Das Programm YACC (so scheint es mir) ist ein STACK/(Keller) (YetAnother) Compiler-Compiler Tool. Doch warum verhält sich dieses Tool so merkwürdig? Beispiel: zahl : NUMMER_TOKEN ; t_var : /* kann leer bleiben */ | zahl zahl { wird als Stack von links nach rechts ausgewertet also zahl1 dann zahl2 } ; verständlich :confused: Also müsste doch mit dem vorliegenden YACC-Code der AsmCode nicht wie: ... call _set_vergleichswert_byvar add esp, 8 push dword [@var_var1] push dword [@var_var2] call _vergleiche_cmpeq ... aussehen, sondern so: ... push dword [@var_var1] push dword [@var_var2] call _set_vergleichswert_byvar add esp, 8 call _vergleiche_cmpeq cmp eax, 1 jne near Le0 ... oder liege ich da jetzt falsch? Für sachdienliche Hinweise bin ich sehr dankbar! Gruß Jens Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 27. April 2009 Teilen Geschrieben 27. April 2009 Hallo Jens, zuerst habe ich falsch verstanden, dass vergleiche_cmpeq pascal-call ist und zwei args hat. Jetzt habe ich set_vergleichswert_byvar vergleiche_cmpeq gesehen. Beide sind C-call. Dann ist dieses Code ganz richtig: ... push dword [@var_var1] push dword [@var_var2] call _set_vergleichswert_byvar add esp, 8 call _vergleiche_cmpeq cmp eax, 1 jne near Le0 ... Und nicht wie: push @Pshow_messageXXX call _show_message sondern, so: push @Pshow_messageXXX call _show_message add esp,4 Wenn _show_message auch C-call ist. Wenn ich später Zeit habe,dann versuche ich dir helfen. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 27. April 2009 Teilen Geschrieben 27. April 2009 (bearbeitet) Der ParserCode erzeugt aus einer Quelldatei NASM (Netwide Assembler) Win32 Code gcc kann AFAIR auch asm Code erzeugen. Options sind -S und -fverbose-asm Hast du das probiert? Bearbeitet 27. April 2009 von Perfiliev Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 1. Mai 2009 Autor Teilen Geschrieben 1. Mai 2009 Hallo Perfiliev, ja habe ich. geht prima. aber das ist nicht der Schwerpunkt. Schwerpunkt ist, dass Yacc anscheinend kein richtigen Code zurüclgibt. Gruß Jens Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 2. Mai 2009 Teilen Geschrieben 2. Mai 2009 Hallo Jens, Schwerpunkt ist, dass Yacc anscheinend kein richtigen Code zurüclgibt. Es gibt nur einen Weg. Debugging, Debugging und noch einmal Debugging. Könntest du DEINE exe-files (lex.exe und yacc.exe)und Quelldatei zu Rapidshare laden? Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 3. Mai 2009 Autor Teilen Geschrieben 3. Mai 2009 Bitte sehr, hoffe das hilft! RapidShare: Easy Filehosting Gruß Jens Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 3. Mai 2009 Teilen Geschrieben 3. Mai 2009 Hallo Jens, pcode.pas PCODE.7z ñêà ÷à òü ñ Ôà éëû@Mail.Ru var1 = 10 var2 = 1 if var1 = var2 showmessage("ist 5") elseif var1 = var2 showmessage("ist nicht 5") endif asm code: BITS 32 cpu 486 extern _exit, _show_message extern _set_vergleichswert_A1, _set_vergleichswert_A2, _set_vergleichswert_bychar extern _vergleiche_cmpeq @var_var1: dd 10 @var_var2: dd 1 @Pshow_message0: db "ist 5",0 @Pshow_message1: db "ist nicht 5",0 segment .text global _start_main _start_main: push ebp mov ebp, esp push dword [@var_var1] push dword [@var_var2] call _set_vergleichswert_byvar add esp,8 call _vergleiche_cmpeq cmp eax, 1 jne near Le0 push @Pshow_message0 call _show_message add esp,4 jmp near Lj0 Le0: push dword [@var_var1] push dword [@var_var2] call _set_vergleichswert_byvar add esp,8 call _vergleiche_cmpeq cmp eax, 1 jne near Le2 push @Pshow_message1 call _show_message add esp,4 jMP near Lj2 Le2: jmp near Lj2 Lj2: jmp near Lj0 Lj0: push dword 0 call _exit leave ret mfg Sergey Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 3. Mai 2009 Autor Teilen Geschrieben 3. Mai 2009 Danke Perfiliev! wenn Du anstelle der pcode.pas, die pcode.y gepostet hättest, wäre mir ein klein wenig Sucharbeit ersparrt geblieben. Aber naja, fürs erste geht das schon. Danke es funktioniert. Woher Du nur die ganzen Ideen herzauberst ;-) Gruß Jens Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
paule22 Geschrieben 9. Mai 2009 Autor Teilen Geschrieben 9. Mai 2009 Hallo Perfiliev! unter: RapidShare: Easy Filehosting habe ich eine abgeänderte Yacc-Datei hochgeladen. Ich habe alle möglichen Varianten + num = num + num = exp + exp = num + exp = exp primitiv programmiert. Klappt auch so weit gut mit var1 = 10.3 var2 = 2.1 if var1 = var2 ... allerdings tritt jetzt das ein Problem auf, wenn ich: var0 = 1.2 var1 = 10.2 var3 = 1.1 + var0 // <-- hier if var3 = ....- dann wird das AssemblerFile derart verstopft ... kannst Du mal nachschauen und ggf. eine Lösung posten? Vielen Dank Jens Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Perfiliev Geschrieben 9. Mai 2009 Teilen Geschrieben 9. Mai 2009 Hallo Jens, wenn ich später Zeit habe, versuche ich helfen mfg Sergey Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.