Namespaces
Variants

Inline assembly

From cppreference.net

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

与C++不同,内联汇编在C语言中被视为扩展功能。它受到条件性支持且由实现定义,这意味着它可能不存在,即使在实现中提供了该功能,其含义也并不固定。

目录

语法

asm ( 字符串字面量 ) ;

说明

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

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

注释

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 内联汇编指南
2. IBM XL C/C++ 内联汇编
3. Intel C++ 内联汇编
4. Visual Studio 内联汇编器
5. Sun Studio 12 Asm 语句
6. 基于 Itanium 的 HP-UX 内联汇编