Le code après conversion n'exécute pas une action donnée [dupliquer]

Dec 18 2020

On m'a donné la tâche de convertir un certain code de C ++ à ASM basé sur la syntaxe AT&T, j'ai donc commencé avec des exemples simples et rencontré le premier problème.

code à partir duquel j'ai commencé l'exercice

void func() {
  int num = 1;
  std::cout << "before: " << num << std::endl;
  num = num << 3;
  std::cout << "after: " << num << std::endl;
}

ce qui donne un résultat:

before: 1
after: 8

ma variable de traduction num est la première variable locale, elle devrait donc être à l'adresse -4 (% ebp)

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

ce qui donne un résultat:

before: 1
after: 1

pourquoi ce code n'a aucun effet sur num var?

Réponses

2 JHBonarius Dec 18 2020 at 02:17

Le code que vous écrivez est très spécifique à l'implémentation. Dans votre cas, le code ne fonctionne probablement pas car vous utilisez ebpun registre d'adressage 32 bits, alors que vous exécutez sur une machine 64 bits, qui utilise rbp.

CEPENDANT, vous abordez cela de manière incorrecte. Soit vous écrivez un assembly pur, soit vous utilisez l'assembly en ligne C (étendu) correct, qui s'interface correctement avec les variables locales. Sinon, le code se cassera dès que vous changerez quelque chose, comme vous l'avez vécu vous-même.

selon cette réponse, l'asm en ligne devrait ressembler à:

asm ( "assembly code"
    : output operands                  /* optional */
    : input operands                   /* optional */
    : list of clobbered registers      /* optional */
);

donc votre code pourrait ressembler à

asm (
    "mov %0, %%eax;"
    "sal $3, %%eax;"
    "mov %%eax, %1;"
    :"=r" (num)
    :"r" (num)
    :"%eax"
);

Cependant, vous n'avez pas besoin de spécifier et d'utiliser eax, ainsi le code pourrait être simplifié (et clarifié) pour

asm (
    "sal $3, %[num];"
    :[num] "+r" (num)
);