2015-06-16 8 views
7

Also habe ich mir vor einiger Zeit selbst x86 Assembly beigebracht und spielte gerade mit Inline Assembly in C++.Ändern von Array-Werten in Funktion - Inline Assembly

Also, was ich tun möchte, ist in einer Funktion Parameter übergeben in einem Array, einem Index (unsigned int) und einer Zahl. Mit Assembly wird dann der Wert in diesem Speicherplatz des Arrays auf den übergebenen Wert geändert. Also sieht der Code so aus.

inline void Set(int pArray[], unsigned int pIndex, int pNum) { 
    __asm { 
     mov ebx, pIndex 
     mov eax, 4 
     mul ebx 
     mov ebx, pNum 

     lea edi, pArray 
     mov [ edi + eax ], ebx 
    } 
} 

int main() { 
    int myArray[ 5 ] = { 1, 2, 3, 4, 5 }; 
    Set(myArray, 2, 7); 
    std::cout << myArray[ 2 ] << std::endl; 
} 

So sollte der Code den Start der Array-Adresse geladen hat, den Index erhalten und es um 4 multiplizieren, so wird der Speicherplatz, dass viele Bytes bewegt wird, und es ändert sich auf den Wert übergeben. Allerdings Wenn ich das tue, bleibt der Wert gleich. Warum das? Was läuft falsch?

+2

Wahrscheinlich wollen Sie 'mov edi, pArray', sonst könnten Sie die Adresse Ihrer Argumentvariablen laden, nicht wo sie hinzeigt. Vielleicht möchten Sie sich selbst auch einen Debugger beibringen :) – Jester

+1

Yup. Das war das Problem. Ich habe dies ursprünglich aus einer Funktion heraus geschrieben, wo das Array im Rahmen von ihm zugegriffen werden konnte, also funktionierte es dann, aber wenn es in der Funktion eingekapselt ist, hat es aufgehört zu arbeiten, so dass es sehr sinnvoll ist, warum ich "mov" benutzt habe "lea". Danke :-) – CMilby

Antwort

1

lea steht für "Load effektive Adresse", Ihre lea setzt die Adresse des Arguments. Was Sie meinen, ist lea edi, [pArray]

Es gibt jedoch zwei weitere Dinge: 1) Sie müssen nicht mit vier multiplizieren. Sie können lea edi, [pArray + 4*ebx] Seit dem "Scale Index Byte" Adressierungsmodus können Sie mit 4 multiplizieren und eine sofortige Adresse hinzufügen.

2) Sie nehmen 32 Bits an. Welchen Computer verwendest du Mitte 2015 noch im 32-Bit-Modus?

Ich bin auf Intel-Syntax Assembly rostig. Darf ich Ihnen empfehlen, die Integration von Assembler und C++ - Code in GCC zu erlernen?

+0

Für 1, 'lea edi, [pArray + 4 * ebx]' ändert sich der Wert nicht. Und für 2 ist das eine gute Frage. Ich bin in Visual Studio Professional 2010 und es wird mir nicht erlauben, 64-Bit-Register zu verwenden. Ich habe es ursprünglich mit 64-Bit-Registern gemacht, aber immer den Fehler C2415 bekommen. – CMilby

+0

Es ist nicht erforderlich, die effektive Adresse zu laden oder die Multiplikationsanweisung zu verwenden. prüfen, was der gcc-Compiler-Explorer zeigt: http://goo.gl/njHPU3 Verwenden Sie einfach die "Skala Index Byte" wie diese Adressierung: 'mov [rdi + rsi * 4], edx' Wo rdi das ist Array-Basisadresse in der Linux-Aufrufkonvention, rsi ist der Indexparameter und edx ist der Wert – EdMaster