Der Code nach der Konvertierung führt keine bestimmte Aktion aus [Duplikat]

Dec 18 2020

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

2 JHBonarius Dec 18 2020 at 02:17

Der Code, den Sie schreiben, ist sehr implementierungsspezifisch. In Ihrem Fall funktioniert der Code wahrscheinlich nicht, weil Sie ebpein 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)
);