El código después de la conversión no ejecuta una acción determinada [duplicar]
Se me asignó la tarea de convertir cierto código de C ++ a ASM basado en la sintaxis de AT&T, así que comencé con ejemplos simples y encontré el primer problema.
código desde el que comencé el ejercicio
void func() {
int num = 1;
std::cout << "before: " << num << std::endl;
num = num << 3;
std::cout << "after: " << num << std::endl;
}
que da un resultado:
before: 1
after: 8
mi variable de traducción num es la primera variable local, por lo que debería estar en la dirección -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;
}
que da un resultado:
before: 1
after: 1
¿Por qué este código no tiene ningún efecto sobre num var?
Respuestas
El código que está escribiendo es muy específico de implementación. En su caso, es probable que el código no funcione porque está usando ebp
un registro de direccionamiento de 32 bits, mientras que está ejecutando en una máquina de 64 bits, que usa rbp
.
SIN EMBARGO te estás acercando a esto incorrectamente. O escribe ensamblado puro o usa el ensamblado en línea C correcto (extendido), que interactúa correctamente con las variables locales. De lo contrario, el código se romperá tan pronto como cambie algo, como lo ha experimentado usted mismo.
de acuerdo con esta respuesta, el asm en línea debería verse así:
asm ( "assembly code"
: output operands /* optional */
: input operands /* optional */
: list of clobbered registers /* optional */
);
para que su código se vea así
asm (
"mov %0, %%eax;"
"sal $3, %%eax;"
"mov %%eax, %1;"
:"=r" (num)
:"r" (num)
:"%eax"
);
Sin embargo, no es necesario especificar ni utilizar eax
, por lo que el código podría simplificarse (y aclararse) para
asm (
"sal $3, %[num];"
:[num] "+r" (num)
);