命名空间
变体
操作

内联汇编

来自 cppreference.cn
< c‎ | language

内联汇编(通常由 asm 关键字引入)提供了在 C 程序中嵌入汇编语言源代码的能力。

与 C++ 不同,内联汇编在 C 中被视为扩展。它是条件支持和实现定义的,这意味着它可能不存在,即使实现提供了它,它也没有固定的含义。

目录

[编辑] 语法

asm ( string_literal ) ;

[编辑] 解释

这种内联汇编语法被 C++ 标准接受,在 C++ 中称为 asm-declaration。 string_literal 通常是用汇编语言编写的简短程序,每当执行此声明时都会执行它。不同的 C 编译器对于 asm-declaration 有着差异很大的规则,并且与周围 C 代码的交互也有不同的约定。

asm-declaration 可以出现在块内(函数体或另一个复合语句),并且,与所有其他声明一样,此声明也可以出现在块外。

[编辑] 注释

MSVC 不支持 ARM 和 x64 处理器上的内联汇编,仅支持 x86 处理器上由 __asm 引入的形式。

当通过 GCC 或 Clang 在 ISO C 模式下编译时(例如,使用选项 -std=c11),必须使用 __asm__ 而不是 asm

[编辑] 示例

演示了 GCC 编译器提供的两种内联汇编语法。此程序仅在 Linux 下的 x86-64 平台上才能正确运行。请注意,“标准内联汇编”在 C 标准中也被视为扩展。

#include <stdio.h>
 
extern int func(void);
// the definition of func is written in assembly language
__asm__(".globl func\n\t"
        ".type func, @function\n\t"
        "func:\n\t"
        ".cfi_startproc\n\t"
        "movl $7, %eax\n\t"
        "ret\n\t"
        ".cfi_endproc");
 
int main(void)
{
    int n = func();
    // gcc's extended inline assembly
    __asm__ ("leal (%0,%0,4),%0"
           : "=r" (n)
           : "0" (n));
    printf("7*5 = %d\n", n);
    fflush(stdout); // flush is intentional
 
    // standard inline assembly in C++
    __asm__ ("movq $60, %rax\n\t" // the exit syscall number on Linux
             "movq $2,  %rdi\n\t" // this program returns 2
             "syscall");
}

输出

7*5 = 35

[编辑] 参考

  • C23 标准 (ISO/IEC 9899:2024)
  • J.5.10 asm 关键字 (p: 待定)
  • C17 标准 (ISO/IEC 9899:2018)
  • J.5.10 asm 关键字 (p: 422)
  • C11 标准 (ISO/IEC 9899:2011)
  • J.5.10 asm 关键字 (p: 580)
  • C99 标准 (ISO/IEC 9899:1999)
  • J.5.10 asm 关键字 (p: 512)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • G.5.10 asm 关键字

[编辑] 参见

C++ 文档 关于 asm 声明

[编辑] 外部链接

1.  GCC 内联汇编 HOWTO
2.  IBM XL C/C++ 内联汇编
3.  Intel C++ 内联汇编
4.  Visual Studio 内联汇编器
5.  Sun Studio 12 Asm 语句
6.  用于基于 Itanium 的 HP-UX 的内联汇编