2013-03-10 2 views
5

Ich versuche, einen Zahlenwert zu erhöhen, indem Sie eine Inline-Assembly in C++ verwenden. Der Grund, warum ich es so mache, ist meine "Inline Assembly" Fähigkeiten zu üben.Ändern eines Zahlenwerts mithilfe einer Inline-Assembly in C++

Nun ist das, was ich bisher getan:

void main() 
{ 
    int x; 
    cout << "Please enter a number "; 
    cin >> x; 
    cout << "The number you entered is: " << x << "\n"; 
    foo(&x); 
    cout << "The new number is: " << x; 
    cin >> x; 
} 

void foo(int *x) 
{ 
    __asm 
    { 
     inc [x] 
    }; 
} 

Und der Wert nie geändert.

+0

Welchen Compiler benutzen Sie? MSVC? – Cameron

+0

Microsoft Visual Studio 2012 –

+5

Möglicherweise möchten Sie den kompilierten Code zerlegen und sehen, ob es das tut, was Sie erwarten. Ich habe gesehen, dass diese Art von Dingen wegen zu wenig oder zu viel Indirekt falsch läuft. Sie können "x" anstatt "x" erhöhen. –

Antwort

7

Sie den Wert x Erhöhen, eigentlich. X in Bezug auf die Assemblersprache ist eine Konstante, die die Adresse x Variable (der Funktion foo) enthält. Diese enthält wiederum die Adresse main 's x. So verursacht inc [x] ein Inkrement des Zeigers. Sie müssen den unter der Adresse [x] gespeicherten Wert erhöhen, z. B. . Natürlich können Sie es nicht in einer Anweisung in Assemblersprache tun, da Sie zwei Speicherzugriffe benötigen: wo der Wert gespeichert ist und tatsächlich Inkrement der Wert. Also würde ich einen Code wie folgt raten:

push eax 
mov eax, [x] 
inc dword ptr [eax] 
pop eax 
+0

Danke! Aus Neugierde habe ich einen anderen Weg versucht, basierend auf deinen Worten: mov eax, x; mov ebx, [eax]; inc [ebx] und faild bleibt der Wert gleich. –

+1

Dies ist MSVC Hilfe für Sie. Es übersetzt automatisch "mov eax, x" in die Bewegung des Variablenwerts. Also, technisch, können Sie die zweite Zeile meines Codes durch 'mov eax, x' ersetzen. In der Tat ist dieses 'x' für MSVC nur ein Index im Stapelrahmen. In reiner Assemblersprache müßten Sie 'mov eax, [ebp + 8]' schreiben, da x die erste Stapelvariable ist. Und wenn Sie 'fastcall' Aufrufkonvention verwenden, würden Sie' inc [eax] 'einfach so schreiben. – Aneri

-3

x86 kann nur ein Register inkrementieren, kein Speicher, also müssen Sie einen Zeiger auf ein Register bewegen. Ich landete mit diesem:

__asm 
{ 
    mov eax, x 
    mov ebx, [eax] 
    inc ebx 
    mov [eax], ebx 
}; 
+5

Huh? Unsinn. 'INC' kann mit Register- oder Speicheroperanden arbeiten. –

+0

Nun, es funktioniert für mich. –

+0

Das "funktioniert", weil es eine zusätzliche Indirektion hinzufügt. Aber 'inc [eax]' würde auch funktionieren. –

0

Vielleicht nützlich es ist zu wissen, wie Visual C++, um den Wert eines int-Zeiger erhöht:

void foo(*x) 
{ 
    (*x)++; 
} 

Im Debug-Modus, wird es übersetzt

(*x)++; 
mov   eax,dword ptr [x] 
mov   ecx,dword ptr [eax] 
add   ecx,1 
mov   edx,dword ptr [x] 
mov   dword ptr [edx],ecx 

Im Freigabemodus wie Aneris Antwort.