c - 如何使用 GCC 在 asm() 中编写多个汇编语句而不使用 "\t\n"分隔每一行?

标签 c gcc assembly x86 inline-assembly

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/

相关文章:

c++ - 类大括号初始化被错误解释为 std::initializer_list 而不是复制构造

c - 解密 x86 汇编函数

可以在函数定义中使用函数原型(prototype) typedef 吗?

c++ - 自动为 Qt 配置套件

c - 基数排序循环错误

c - 为 C 类型添加额外的标签

assembly - mov 立即数到 64 位寄存器的十六进制机器代码没有 REX.W 前缀?

c - 如何从 C 代码调用汇编函数?

c - typedef 结构在语法上是如何工作的?

c - Libcurl 问题 - "initializer element is not constant"