O código após a conversão não executa uma determinada ação [duplicar]

Dec 18 2020

Recebi a tarefa de converter um determinado código de C ++ para ASM com base na sintaxe AT&T, então comecei com exemplos simples e encontrei o primeiro problema.

código a partir do qual comecei o exercício

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

o que dá um resultado:

before: 1
after: 8

minha variável de tradução num é a primeira variável local, então deve estar no endereço -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;
}

o que dá um resultado:

before: 1
after: 1

por que este código não tem efeito sobre num var?

Respostas

2 JHBonarius Dec 18 2020 at 02:17

O código que você está escrevendo é muito específico para implementação. No seu caso, o código provavelmente não funciona porque você está usando ebpum registro de endereçamento de 32 bits, enquanto está executando em uma máquina de 64 bits, que usa rbp.

NO ENTANTO, você está abordando isso incorretamente. Ou você escreve um assembly puro ou usa o assembly embutido C correto (estendido), que faz interface com as variáveis ​​locais. Caso contrário, o código será quebrado assim que você mudar algo, como você mesmo experimentou.

de acordo com esta resposta, o conjunto em linha deve ser semelhante a:

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

para que seu código se pareça

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

No entanto, você não precisa especificar e usar eax, portanto, o código pode ser simplificado (e esclarecido) para

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