El código después de la conversión no ejecuta una acción determinada [duplicar]

Dec 18 2020

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

2 JHBonarius Dec 18 2020 at 02:17

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 ebpun 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)
);