Entwickler-Ecke
Algorithmen, Optimierung und Assembler - Mathemetische Berechnung zu Assembler
ScorpionKing - Di 05.04.05 19:56
Titel: Mathemetische Berechnung zu Assembler
Hi Leute,
ich habe folgendes Problem: Ich will eine Berechnung (extended, also mit komma) in Assembler rechnen.
Wie bekomme ich zum Beispiel 1/6*a+4/2 in einen Asm-Code?
MfG, ScorpionKing!
Moderiert von
Christian S.: Topic aus Off Topic verschoben am Di 05.04.2005 um 20:06
BenBE - Di 05.04.05 20:13
Titel: Re: Mathemetische Berechnung zu Assembler
ScorpionKing hat folgendes geschrieben: |
Hi Leute,
ich habe folgendes Problem: Ich will eine Berechnung (extended, also mit komma) in Assembler rechnen.
Wie bekomme ich zum Beispiel 1/6*a+4/2 in einen Asm-Code?
MfG, ScorpionKing! |
Eigentlich ganz einfach:
1. Umwandeln in RPN-Schreibweise:
Aus
1/6*a+4/2 wird
1 6 / a * 4 2 / +
2. Vereinfachen:
3. Schreiben der FPU-Befehle:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| FILD WORD PTR [@@Data_Int2] FILD WORD PTR [@@Data_Int6] FLD TBYTE PTR [a] FDIVP FADDP
JMP @@SkipData
@@Data_Int6: DW 6 @@Data_Int2: DW 2
@@SkipData: |
* TBYTE PTR kann entfallen, wenn Speichervariablen genutzt werden, bei Registern gibt es die Speichergröße und somit den Typ an. Für das Laden von Integern verwendet man FILD.
** Laden von Integern oder anderen Konstanten geht am einfachsten über DWord-Preallocations im Code-Segment. Für die Werte 0, 1 und Pi gibt es die Befehle FLDZ, FLD1 und FLDPI (sowie noch weitere Konstanten, die man häufiger braucht).
*** Bei FDIV und FSUB ist ST0 immer Zielregister. und der erste Operand. Die Reverse-Operationen vertauschen die Quelloperanden:
FDIV ST(0), ST(i) :arrow: ST(0) := ST(0) / ST(i)
FDIVR ST(0), ST(i) :arrow: ST(0) := ST(i) / ST(0)
Das P hinter dem Befehl sagt nur, dass der Zweite Operand vom Floating Point Stack entfernt werden soll.
Die Kurzformen FDIVP und FDIVRP haben die Impliziten Argumente ST(0), ST(1).
That's it ^^
tommie-lie - Di 05.04.05 20:27
Titel: Re: Mathemetische Berechnung zu Assembler
BenBE hat folgendes geschrieben: |
1. Umwandeln in RPN-Schreibweise:
Aus 1/6*a+4/2 wird 1 6 / a * 4 2 / +
2. Vereinfachen:
|
Mit der umgekehrten polnischen Notation arbeite ich nicht täglich, aber steht da nicht 6/a+2 und müsste da nicht eigentlich a/6+2 stehen? :gruebel:
ScorpionKing - Di 05.04.05 20:27
und wie sieht das in delphi aus?
tommie-lie - Di 05.04.05 20:29
ScorpionKing hat folgendes geschrieben: |
und wie sieht das in delphi aus? |
So:
Delphi-Quelltext
1:
| result := 1/6 *a + 4/2; |
BenBE - Di 05.04.05 21:05
Titel: Re: Mathemetische Berechnung zu Assembler
tommie-lie hat folgendes geschrieben: |
Mit der umgekehrten polnischen Notation arbeite ich nicht täglich, aber steht da nicht 6/a+2 und müsste da nicht eigentlich a/6+2 stehen? :gruebel: |
Nein, da Du nach dem Stackprinzip arbeitest ...
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| 6 / a + 2 --------- + 6 / a 2 --------- + / 2 6 a |
Nun liest man den Baum top-->down, left-->right in pre-order:
Und durch umkehren erhält man die RPN (post-order, bottom-->up):
Wenn man aber die Ausgangsgleichung noch etwas vereinfacht, kann man durch anwenden des Distributiv-Gesetzes die Argumente der Addition vertauschen und so alle Zahlen hintereinander bekommen:
tommie-lie - Di 05.04.05 21:21
Titel: Re: Mathemetische Berechnung zu Assembler
BenBE hat folgendes geschrieben: |
Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| 6 / a + 2 --------- + 6 / a 2 --------- + / 2 6 a |
Nun liest man den Baum top-->down, left-->right in pre-order:
Und durch umkehren erhält man die RPN (post-order, bottom-->up):
|
Schon, aber ScorpionKings Term sah so aus:
ScorpionKing hat folgendes geschrieben: |
1/6*a+4/2 |
Und von links nach rechts gelesen, da beides Punktrechnung ist, ist 1/6*a bei mir a/6 und nicht 6/a ;-)
Oder ist es schon zu spät für mich? :gruebel:
Aber danke für die Erklärung, jetzt muss ich mir RPN nicht jedesmal zu Fuß überlegen, sondern habe ein Schema für sowas, falls die Terme mal länger werden ;-)
Moritz M. - Di 05.04.05 21:22
Titel: Re: Mathemetische Berechnung zu Assembler
Nochmal kurze Frage an BenBE (Wohl die gleiche wie tommie-lie)
Wenn ich 1/6*a+4/2 vereinfache, komm ich auf a/6 + 2
In RPN wäre das doch a 6 / 2 +, oder?
Wie kommst du auf 2 6 a / +?
tommie-lie - Di 05.04.05 21:32
Titel: Re: Mathemetische Berechnung zu Assembler
Moritz M. hat folgendes geschrieben: |
In RPN wäre das doch a 6 / 2 +, oder? |
Unvereinfacht ja.
Moritz M. hat folgendes geschrieben: |
Wie kommst du auf 2 6 a / +? |
Nein, das ist nicht meine Frage.
Vorrausgesetzt Bens Term stimmt, wäre 6 a / 2 + umgestellt (nicht vereinfacht im Sinne, daß es einfacher ist :mrgreen:) 2 6 a / +. Siehe Bens Anhängsel:
BenBE hat folgendes geschrieben: |
Wenn man aber die Ausgangsgleichung noch etwas vereinfacht, kann man durch anwenden des Distributiv-Gesetzes die Argumente der Addition vertauschen und so alle Zahlen hintereinander bekommen:((2) (6 a) /) + |
Vorraussetzung natürlich, der Parser beachtet die Regel "Punkt- vor Strich-Rechnung" kann man dann die Klammern weg lassen und man erhält Bens Term:
Ich schiebe 2 auf den Stack. Ich schiebe 6 auf den Stack. Ich schiebe a auf den Stack. Ich dividiere die obersten beiden Elemente des Stacks (und hier liegt bei mir die Verwirrung, ich Teile 6/a, dabei ist 1/6*a aber a/6) und schiebe das Ergebnis wieder auf den Stack. Dann addiere ich die obersten beiden Elemente des Stacks (2 und das Ergebnis der Division). Fertig.
ScorpionKing - Mi 06.04.05 12:34
ja, den schau ich mir mal an! danke!
MfG, Scorpion!
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!