2015-06-16 19 views
7

Così mi sono insegnato x86 Assembly poco fa e stavo solo giocando con l'assembly inline in C++.Modifica dei valori dell'array nella funzione - Assemblaggio in linea

Quindi, quello che voglio fare è un parametro di funzioni, passare un array, un indice (unsigned int) e un numero. Con l'assembly verrà quindi modificato il valore in quella posizione di memoria dell'array sul valore passato. Quindi il codice sembra così.

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; 
} 

Così il codice deve caricare l'inizio dell'indirizzo matrice, ottenere l'indice e moltiplicarlo per 4 quindi la posizione di memoria è mosso da quel numero di byte, e cambia al valore passato. Tuttavia, quando lo faccio, il valore rimane lo stesso. Perché? Cosa sta andando storto?

+2

Probabilmente si desidera 'mov edi, pArray' altrimenti si potrebbe caricare l'indirizzo della variabile argomento, non dove si sta puntando. Potresti anche insegnare a te stesso usando un debugger :) – Jester

+1

Sì. Questo era il problema Ho scritto questo fuori da una funzione originariamente in cui l'array poteva essere utilizzato nell'ambito di esso in modo che funzionasse allora, ma quando incapsulato nella funzione ha smesso di funzionare, quindi ha molto senso perché avrei dovuto usare "mov" e non "lea". Grazie :-) – CMilby

risposta

1

lea sta per "Carica indirizzo effettivo", il tuo lea mette l'indirizzo dell'argomento. Cosa intendi dire è lea edi, [pArray]

Tuttavia, ci sono altre due cose: 1) Non devi moltiplicare per quattro. È possibile eseguire lea edi, [pArray + 4*ebx] Poiché la modalità di indirizzamento del "byte dell'indice di scala" consente di moltiplicare per 4 e aggiungere un indirizzo immediato.

2) Si presuppone che 32 bit. Quale computer stai usando a metà del 2015 funziona ancora in modalità 32 bit?

Sono arrugginito sull'assembly della sintassi Intel. Posso consigliarti di imparare l'integrazione di assembler e codice C++ in GCC? https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

+0

Per 1, 'lea edi, [pArray + 4 * ebx]' non modifica il valore. E per 2, questa è una grande domanda. Sono in Visual Studio Professional 2010 e non mi consentirà di utilizzare registri a 64 bit. L'ho fatto in origine con i registri a 64-bit ma continuavo a ricevere l'errore C2415. – CMilby

+0

Non è necessario caricare l'indirizzo effettivo né utilizzare l'istruzione di moltiplicazione. Controllare ciò che il compilatore gcc Explorer mostra: http://goo.gl/njHPU3 basta usare la "scala di indice di byte" affrontare in questo modo: ' mov [RSI + RSI * 4], edx' Dove RDI è il indirizzo di base dell'array nella convenzione di chiamata linux, rsi è il parametro index ed edx è il valore – EdMaster