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],ebx

    Im 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. ]


Anmelden zum Antworten