Der Code nach der Konvertierung führt keine bestimmte Aktion aus [Duplikat]
Ich erhielt die Aufgabe, einen bestimmten Code basierend auf der AT & T-Syntax von C ++ in ASM zu konvertieren. Daher begann ich mit einfachen Beispielen und stieß auf das erste Problem.
Code, mit dem ich die Übung gestartet habe
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
was ein Ergebnis gibt:
before: 1
after: 8
Meine Übersetzungsvariable num ist die erste lokale Variable, daher sollte sie die Adresse -4 (% ebp) haben.
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
asm (
"mov -4(%ebp), %eax \n"
"sall $3, %eax \n"
"mov %eax, -4(%ebp) \n"
);
std::cout << "after: " << num << std::endl;
}
was ein Ergebnis gibt:
before: 1
after: 1
Warum hat dieser Code keine Auswirkung auf num var?
Antworten
Der Code, den Sie schreiben, ist sehr implementierungsspezifisch. In Ihrem Fall funktioniert der Code wahrscheinlich nicht, weil Sie ebp
ein 32-Bit-Adressierungsregister verwenden, während Sie auf einem 64-Bit-Computer arbeiten, der verwendet rbp
.
JEDOCH Sie diese falsch nähern. Entweder schreiben Sie eine reine Assembly oder Sie verwenden die richtige (erweiterte) C-Inline-Assembly, die korrekt mit lokalen Variablen verbunden ist. Andernfalls wird der Code unterbrochen, sobald Sie etwas ändern, wie Sie es selbst erlebt haben.
Nach dieser Antwort sollte der Inline-Asm folgendermaßen aussehen:
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
So könnte Ihr Code aussehen
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
Sie müssen jedoch nicht angeben und verwenden eax
, sodass der Code vereinfacht (und präzisiert) werden kann
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);