命名空间
变体
操作

内联汇编

来自 cppreference.com
< c‎ | 语言

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

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

内容

[编辑] 语法

asm ( 字符串字面量 ) ;

[编辑] 解释

这种内联汇编语法被 C++ 标准接受,在 C++ 中被称为 asm-declaration字符串字面量 通常是用汇编语言编写的短程序,每当执行此声明时就会执行。不同的 C 编译器对 asm-declarations 都有不同的规则,以及与周围 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: TBD)
  • 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 内联汇编