O código após a conversão não executa uma determinada ação [duplicar]
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
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 ebp
um 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)
);