Funktion in ASM programmieren
-
Jo, ungefaehr so hatte ich mir das gedacht.
Auch noch ein Vorschlag:
mov edi,[mat] mov esi,offset Pattern0 mov ecx,15 rep movsd ... Pattern0 dd 1.0, 0.0, 0.0, 0.0, 0.0 dd 1.0, 0.0, 0.0, 0.0, 0.0 dd 1.0, 0.0, 0.0, 0.0, 0.0
-
__forceinline void Test4( D3DMATRIX *mat ) { const float A = 1.0f; const float B = 0.0f; _asm { mov eax,[mat] mov ebx, A mov ecx, B mov [eax],ebx mov [eax+14h],ebx mov [eax+28h],ebx mov [eax+3Ch],ebx . . .
mov eax,[mat] Adresse von mat in den eax Register mov ebx, A ebx und ecx werden mit den Werte in A und B gefüllt mov ecx, B mov [eax],ebx eax hat jetzt den Wert 1.0f mov [eax+14h],ebx Adresse+14h(Dezimal 20) bekommen Wert 1.0f
ist das richtig? Die eckigen Klammer. Ist es so etwas wie *variable in C? Und was hat es mit dem Wert 14h auf sich. Wie kommt man darauf?
-
Die eckigen Klammern stehen fuer einen Speicherzugriff. Kann man also in sofern nicht unbedingt mit *Variable in c vergleichen...
mov eax,[mat] Adresse von mat in den eax Register
hier wird nicht die Addresse von mat in eax geladen, sondern der Wert, der an der Adresse von mat im Speicher steht.
mov [eax],ebx eax hat jetzt den Wert 1.0f
nicht ganz: 1.0 wird an die Speicheraddresse geschrieben, auf die eax zeigt.
-
Ok,
mov [eax],ebx eax hat jetzt den Wert 1.0f
**
nicht ganz: 1.0 wird an die Speicheraddresse geschrieben, auf die eax zeigt.
**mov eax,ebx hätte auch funktioniert, oder?
Noch etwas.
mov [eax],1 Über einen "Speicherzugriff" schreibe ich den Wert 1 in das Register eax. mov [eax+14h],2 Adresse+14h wird der Wert 2 geschrieben.
Wie groß ist den so ein Register? Ich meine das ich da +14h machen kann.
-
Wie groß ist den so ein Register?
Kommt auf den Prozessor drauf an. Beim x86er 32-bit
-
Original erstellt von <Gombolo>**
mov eax,ebx hätte auch funktioniert, oder?
**Eben nicht!
mov eax,ebx != mov [eax],ebxIm 1. Fall wird ebx in eax geschrieben. => eax wird veraendert. Im Speicher wird nichts veraendert. => kein Speicherzugriff => keine eckigen Klammern
Im 2. Fall wird eax als Pointer in den Speicher benutzt. Dabei aendert sich der Wert von eax nicht! Lediglich ein 4Byte grosser bereich im Speicher wird hier veraendert. (ebx=32Bit=4Byte) Irgendwelche anderen Register werden auch nicht veraendert. => Speicherzugriff => eckige Klammern
Original erstellt von <Gombolo>**
mov [eax],1 Über einen "Speicherzugriff" schreibe ich den Wert 1
in das Register eax.
**Die Register sind die einzigen "Variablen", die nicht im Speicher liegen. Wie soll dann ueber einen "Speicherzugriff" ein Register veraendert werden?
Also nochmal: Hier wird ein ???byte (nicht angegeben) grosser Speicherbereich veraendert, auf den eax zeigt und nicht das Register selbst.
So wuerde das uebrigens kein vernuenftiger Compiler akzeptieren, da wie oben erwaehnt nicht angegeben ist, wie gross der Speicherbereich ist, der veraendert werden soll. Es waere hier moeglich einen 1byte/1word(2byte)/1dword(4byte) grossen Speicherbereich mit dieser 1 zu fuellen.
So wuerde ein dword grosser Speicherbereich (auf den eax zeigt) mit dieser 1 belegt werden:mov [dword ptr eax],1
Original erstellt von <Gombolo>**
mov [eax+14h],2 Adresse+14h wird der Wert 2 geschrieben.Wie groß ist den so ein Register? Ich meine das ich da +14h machen kann.
**Ich hoffe doch, dass sich diese Frage nach meinen Ausfuehrungen erledigt hat?
[ Dieser Beitrag wurde am 30.12.2002 um 14:58 Uhr von Nobuo T editiert. ]
-
So, hab mir die letzten Beiträge nich so genau angeschaut (ging eh "nur" um den Speicherzugriff via []). Aber Ich habe da Oben ding im Code gesehen, die meiner Ansicht nach falsch sind. Ich sage gleich ich benutze NASM-Syntax für den ASM-Code.
const A 0.0f asm{ mov eax, A mov [Addr], eax } // ist NICHT äquivalent zu asm{ fldz fstp Addr }
Ein float Wert ist 80 Bit (!!!) gross, der passt nicht in eax!!!
ich würde vorschlagen den ersten float jeweils von der FPU zu holen, und dann mit "normalen" instruktionen fortfahren. Entscheidend ist auch ob die Werte der Matrix direkt nebeneinanderliegen oder nicht.Code könnt dann so aussehen:
//ich nehme der einfaheit halber an, das die Werte an die Adressen // Mat_1, Mat2, Mat_3, .., kopiert werden sollen asm{ fldz fstp Mat_1 mov esi, Mat_1 mov edi, Mat_2 movsd ;kopiere die 1. 32 bit movsd ;kopiere die 2. 32 bit movsw ;kopiere die letzten 16 bit mov esi, Mat_1 mov edi, Mat_3 movsd ;kopiere die 1. 32 bit movsd ;kopiere die 2. 32 bit movsw ;kopiere die letzten 16 bit mov esi, Mat_1 mov edi, Mat_4 movsd ;kopiere die 1. 32 bit movsd ;kopiere die 2. 32 bit movsw ;kopiere die letzten 16 bit }
habe allerdings gerade nochmal nachgeschaut, der fst(p) mem32 braucht nur 2 Takte ab dem Pentium, daher währe es u.U. doch sinvoll einfach
asm{ fldz fst Mat_1 fst Mat_2 fst Mat_3 fstp Mat_4 }
zu machen.
mfg
-bg-und ein frohes neues, falls ich vorher nicht mehr dazu komme
-
Original erstellt von -bg-
Ein float Wert ist 80 Bit (!!!) gross, der passt nicht in eax!!!hm?? Seit wann denn das? Da musst Du mir mal deine Quelle(n) offenlegen
Meine kannst Du hier haben (aus dem c++-Lehrgang fuer MSVC++ 6.0):
If you don't need 15 digits precision, and you don't need the massive range of values provided by double variables, you can opt to use the keyword float to declare floating point variables occupying 4 bytes.
-
z.B.
http://www.nuvisionmiami.com/books/asm/files/chapt_17.pdf Seite 17 mitte "Data Registers"auch in meinen ganzen FPU tuts und der Intel Doku sind die Register der FPU 80bit groß.
Muss allerdings zugeben, dass sizeof(float)==4 true ist, und sizeof(double)==8.
Das ganze scheint ein wenig blöd zu sein, der Hilfe nach ist deim bcc sizeof(long double)==10, beim mingw (gcc) ist sizeof(long double)==12.Die FPU kann nur mit 80bit Werten rechnen, kann jedoch andere Werte laden und speichern.
also wohl ein Fehler meinerseits.
mfg
-bg-
-
-sorry ich hatte den letzten post nicht richtig gelesen,da hat sich ja schon alles geklärt-
[ Dieser Beitrag wurde am 02.01.2003 um 01:53 Uhr von Bigor editiert. ]