如何在asm()中编写多个汇编语句而不使用\";使用GCC分隔各行?

如何在asm()中编写多个汇编语句而不使用\";使用GCC分隔各行?,c,gcc,assembly,x86,inline-assembly,C,Gcc,Assembly,X86,Inline Assembly,如何在asm()中编写多个汇编语句,而不使用GCC分隔各行“\t\n” 我见过一些教科书在asm()中编写多个汇编语句,如下所示: asm(" movl $4, %eax movl $2, %ebx addl %eax, %ebx ... "); 但是,我的编译器(GCC)无法识别此语法。相反,我必须依靠“\t\n”分隔每一行或使用多个asm(): 或 如何在没有“\t\n”或重复asm()的情况下启用“clean”语法?GCC 内联程序集是不明智的,因为您在不通知编译器的情况下更改了寄存器。

如何在asm()中编写多个汇编语句,而不使用GCC分隔各行“\t\n”

我见过一些教科书在
asm()
中编写多个汇编语句,如下所示:

asm("
movl $4, %eax
movl $2, %ebx
addl %eax, %ebx
...
");
但是,我的编译器(GCC)无法识别此语法。相反,我必须依靠
“\t\n”
分隔每一行或使用多个
asm()

如何在没有
“\t\n”
或重复
asm()
的情况下启用“clean”语法?

GCC 内联程序集是不明智的,因为您在不通知编译器的情况下更改了寄存器。您应该使用适当的输入和输出约束。使用内联汇编程序应该被用作一种工具,并且您应该确切地理解您正在做什么。GCC的内联程序集是非常不可原谅的,因为似乎有效的代码甚至可能不正确

也就是说,用
\n\t
结束每个字符串会使生成的汇编代码看起来更干净。通过使用
-S
参数编译以生成相应的汇编代码,可以看到这一点。您可以选择使用
(分号)。这将分隔每条指令,但将在同一行上输出所有指令

另一个选项是使用C行连续字符
\
(反斜杠)。尽管以下内容将在生成汇编代码中生成过多的空白,但它将按预期编译:

int main()
{
    __asm__("movl $4, %eax; \
             movl $2, %ebx; \
             addl %eax, %ebx");
}
虽然这是一种方法,但我并不是说这是一种好的形式。我更喜欢第二个示例中使用的格式,该格式使用
\n\t
,不带行连续字符


关于将多条指令拆分为单独的ASM语句:

asm("movl $4, %eax");
asm("movl $2, %ebx");
asm("addl %eax, %ebx");
这是有问题的。编译器可以相对地对它们重新排序,因为它们是没有依赖关系的基本汇编程序。编译器可以生成以下代码:

movl $4, %eax
addl %eax, %ebx
movl $2, %ebx
这当然不会产生您期望的结果。当您将所有指令放在单个ASM语句中时,它们将按照您指定的顺序生成


MSVC/C++

32位微软C和C++编译器支持对语言的扩展,允许在“代码”>“代码”>“<代码> >和<代码> } /代码>之间放置多行内联汇编。使用这种机制,您不会将内联程序集放在C字符串中;不需要使用换行符;并且不需要以

结束语句(分号)

这方面的一个例子是:

__asm {
    mov eax, 4
    mov ebx, 2
    add ebx, eax
}

你有什么问题?语法是“干净”的,带有换行符。不确定为什么要使用这些选项卡。内联汇编应该少用,如果不可避免的话,也只能用于短代码段。我认为正确的解决方案是不首先使用内联汇编。:)解决方案很简单:使用分离的汇编文件。为什么不直接写清楚的、可维护的C++,而让编译器担心ASM?除非你正在做一些非常低级的事情或优化一个非常关键的函数(并且真正知道你在做什么),否则编译器可能会编写比你更好的asm。什么样的建议是“你永远不应该编写汇编程序”?天哪,这里没有人做过实验吗?谢谢@Michael-终于有了回答我的问题的答案。但我还是觉得奇怪,比如说《黑客手册》,使用了我第一次提到的语法。@Shuzheng我只有第二版的《黑客手册》(在线)很明显,他们在这方面犯了一些错误。在第二版中,虽然他们在第4章第79页的示例中得到了正确的语法。在这种情况下,它们使用反斜杠行连续字符,并以
结束每一行正如我在回答中所做的,但我个人不喜欢这样做。使用
asm volatile
强制编译器按顺序生成代码
movl $4, %eax
addl %eax, %ebx
movl $2, %ebx
__asm {
    mov eax, 4
    mov ebx, 2
    add ebx, eax
}