转换后的代码不执行给定的动作

The code after conversion does not execute a given action

我的任务是根据 AT&T 语法将某个代码从 C++ 转换为 ASM,所以我从简单的示例开始,遇到了第一个问题。

我开始练习的代码

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

结果为:

before: 1
after: 8

我的翻译 变量 num 是第一个局部变量,所以它应该在地址 -4(%ebp)

void func() {
  int num = 1;
  std::cout << "before: " << num << std::endl;
  asm (
    "mov -4(%ebp), %eax         \n"
    "sall , %eax              \n"
    "mov %eax, -4(%ebp)         \n"
  );
  std::cout << "after: " << num << std::endl;
}

结果为:

before: 1
after: 1

为什么这段代码对 num var 没有影响?

您正在编写的代码是非常特定于实现的。在您的情况下,代码可能不起作用,因为您使用的是 ebp 这是一个 32 位寻址寄存器,而您在 64 位机器上使用 运行,它使用 rbp .

但是 您的处理方式不正确。您要么编写纯汇编,要么使用正确的(扩展的)C 内联汇编,它们可以正确地与局部变量交互。否则一旦您更改某些内容,代码就会崩溃,正如您自己所经历的那样。

according to this answer 内联汇编应该如下所示:

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

所以你的代码看起来像

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

但是,您不需要指定和使用 eax,因此代码可以简化(并明确)为

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