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