转换后的代码不执行给定的动作
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)
);
我的任务是根据 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)
);