如何使用 GCC 在没有“\t\n”分隔每一行的情况下在 asm() 中编写多个汇编语句?
How to write multiple assembly statements within asm() without "\t\n" separating each line using GCC?
How to write multiple assembly statements within asm() without "\t\n" separating each line using GCC?
我看过一些教科书在 asm()
内写了多个汇编语句,如:
asm("
movl , %eax
movl , %ebx
addl %eax, %ebx
...
");
但是,我的编译器 (GCC) 无法识别此语法。相反,我必须依靠 "\t\n"
分隔每一行或使用多个 asm()
:
asm(
"movl , %eax\t\n"
"movl , %ebx\t\n"
"addl %eax, %ebx\t\n"
...);
或
asm("movl , %eax");
asm("movl , %ebx");
asm("addl %eax, %ebx");
...
如何在没有 "\t\n"
或重复 asm()
的情况下启用 "clean" 语法?
海湾合作委员会
你的内联汇编是不明智的,因为你在没有通知编译器的情况下改变了寄存器。你应该使用 GCC's extended inline assembler with proper input and output constraints. Using inline assembler should be used as a last resort 并且你应该准确地理解你在做什么。 GCC 的内联汇编是非常无情的,因为看起来有效的代码甚至可能不正确。
也就是说,每个字符串以 \n\t
结尾会使生成的 assembler 代码看起来更清晰。你可以通过使用 -S
参数编译生成相应的汇编代码来看到这一点。您可以选择使用 ;
(分号)。这将分隔每条指令,但将在同一 assembler 行上输出所有指令。是的,这很重要:查看 -S
输出是了解编译器如何将操作数替换到您的 asm 模板并将其自己的代码放在您的周围的好方法。
另一种选择是使用 C 行继续字符 \
(反斜杠)。尽管以下内容会在生成汇编代码时生成过多的白色 space,但它会按预期进行编译和 assemble:
int main()
{
__asm__("movl , %eax; \
movl , %ebx; \
addl %eax, %ebx"
::: "eax", "ebx");
}
虽然这是一种实现方式,但我并不是说这是一种好的形式。我更喜欢你在第二个例子中使用的形式,使用 \n\t
没有行继续字符。
关于将多条指令拆分成单独的 ASM 语句:
asm("movl , %eax");
asm("movl , %ebx"); // unsafe, no operands specifying connections
asm("addl %eax, %ebx");
这是有问题的。编译器可以相对于彼此重新排序它们,因为它们是基本的 assembler,没有依赖关系。编译器可以生成此代码:
movl , %eax
addl %eax, %ebx
movl , %ebx
这当然不会产生您期望的结果。当您将所有指令放在单个 ASM 语句中时,它们将按照您指定的顺序生成。
MSVC/C++
32 位 Microsoft C 和 C++ 编译器支持语言扩展,允许您在 __asm {
和 }
之间放置多行内联汇编。使用这种机制,您不会将内联程序集放在 C 字符串中;不需要使用续行;并且无需以 ;
(分号)结束语句。
这方面的一个例子是:
__asm {
mov eax, 4
mov ebx, 2
add ebx, eax
}
你也可以只做...
int main()
{
__asm__(
"movl , %eax;"
"movl , %ebx;"
"addl %eax, %ebx;"
);
}
How to write multiple assembly statements within asm() without "\t\n" separating each line using GCC?
我看过一些教科书在 asm()
内写了多个汇编语句,如:
asm("
movl , %eax
movl , %ebx
addl %eax, %ebx
...
");
但是,我的编译器 (GCC) 无法识别此语法。相反,我必须依靠 "\t\n"
分隔每一行或使用多个 asm()
:
asm(
"movl , %eax\t\n"
"movl , %ebx\t\n"
"addl %eax, %ebx\t\n"
...);
或
asm("movl , %eax");
asm("movl , %ebx");
asm("addl %eax, %ebx");
...
如何在没有 "\t\n"
或重复 asm()
的情况下启用 "clean" 语法?
海湾合作委员会
你的内联汇编是不明智的,因为你在没有通知编译器的情况下改变了寄存器。你应该使用 GCC's extended inline assembler with proper input and output constraints. Using inline assembler should be used as a last resort 并且你应该准确地理解你在做什么。 GCC 的内联汇编是非常无情的,因为看起来有效的代码甚至可能不正确。
也就是说,每个字符串以 \n\t
结尾会使生成的 assembler 代码看起来更清晰。你可以通过使用 -S
参数编译生成相应的汇编代码来看到这一点。您可以选择使用 ;
(分号)。这将分隔每条指令,但将在同一 assembler 行上输出所有指令。是的,这很重要:查看 -S
输出是了解编译器如何将操作数替换到您的 asm 模板并将其自己的代码放在您的周围的好方法。
另一种选择是使用 C 行继续字符 \
(反斜杠)。尽管以下内容会在生成汇编代码时生成过多的白色 space,但它会按预期进行编译和 assemble:
int main()
{
__asm__("movl , %eax; \
movl , %ebx; \
addl %eax, %ebx"
::: "eax", "ebx");
}
虽然这是一种实现方式,但我并不是说这是一种好的形式。我更喜欢你在第二个例子中使用的形式,使用 \n\t
没有行继续字符。
关于将多条指令拆分成单独的 ASM 语句:
asm("movl , %eax");
asm("movl , %ebx"); // unsafe, no operands specifying connections
asm("addl %eax, %ebx");
这是有问题的。编译器可以相对于彼此重新排序它们,因为它们是基本的 assembler,没有依赖关系。编译器可以生成此代码:
movl , %eax
addl %eax, %ebx
movl , %ebx
这当然不会产生您期望的结果。当您将所有指令放在单个 ASM 语句中时,它们将按照您指定的顺序生成。
MSVC/C++
32 位 Microsoft C 和 C++ 编译器支持语言扩展,允许您在 __asm {
和 }
之间放置多行内联汇编。使用这种机制,您不会将内联程序集放在 C 字符串中;不需要使用续行;并且无需以 ;
(分号)结束语句。
这方面的一个例子是:
__asm {
mov eax, 4
mov ebx, 2
add ebx, eax
}
你也可以只做...
int main()
{
__asm__(
"movl , %eax;"
"movl , %ebx;"
"addl %eax, %ebx;"
);
}