Namespaces
Variants

asm declaration

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous
Inline assembly

asm 声明 提供了在 C++ 程序中嵌入汇编语言源代码的能力。该声明是 有条件支持且 (C++11 起) 由实现定义的, 这意味着 它可能不存在,并且即使由实现提供时, (C++11 起) 它也不具有固定含义。

目录

语法

attr  (可选) asm ( string-literal ) ; (直至 C++26)
attr  (可选) asm ( balanced-token-seq ) ; (自 C++26 起)
attr - (since C++11) 任意数量的 属性
string-literal - 字符串字面量 中的定义相同,包括原始字符串字面量
balanced-token-seq - 括号、方括号和大括号保持平衡的令牌序列;对 balanced-token-seq 的任何限制及其含义由实现定义

说明

balanced-token-seq 通常是一个表示用汇编语言编写的短程序的字符串字面量,每当执行此声明时就会执行该程序。不同的 C++ 编译器对于 asm-declaration 有着截然不同的规则,并且与周围 C++ 代码交互的约定也各不相同。

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

注释

特性测试宏 标准 特性
__cpp_constexpr 201907L (C++20) constexpr 函数中的 默认初始化 asm 声明

关键词

asm

示例

演示了GCC/Clang编译器提供的两种内联汇编语法。此程序仅在Linux系统的x86_64平台上可正确运行。

#include <iostream>
extern "C" int func(int x);
// the definition of func is written in assembly language
// raw string literal could be very useful
asm(R"(
.globl func
    .type func, @function
    func:
    .cfi_startproc
    movl %edi, %eax /* x is in RDI, see x86-64 calling convention */
    addl $1, %eax
    ret
    .cfi_endproc
)");
int main()
{
    int n = func(0110);
    // formerly non-standard inline assembly, made comforming by P2361R6
    asm ("leal (%0,%0,4),%0"
         : "=r" (n)
         : "0" (n));
    std::cout << "73*5 = " << n << std::endl; // flush is intentional
    // standard inline assembly
    asm ("movq $60, %rax\n" // the exit syscall number on Linux
         "movq $2,  %rdi\n" // this program returns 2
         "syscall");
}

输出:

73*5 = 365

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时的行为 正确行为
CWG 195 C++98 要求支持所有asm声明 改为有条件支持
CWG 2262 C++11 属性不能应用于asm声明 允许应用

参考文献

  • C++26 标准 (ISO/IEC 14882:2026):
  • 9.10 asm 声明 [dcl.asm]
  • C++23 标准 (ISO/IEC 14882:2024):
  • 9.10 asm 声明 [dcl.asm]
  • C++20 标准 (ISO/IEC 14882:2020):
  • 9.10 asm 声明 [dcl.asm]
  • C++17 标准 (ISO/IEC 14882:2017):
  • 10.4 asm 声明 [dcl.asm]
  • C++14 标准 (ISO/IEC 14882:2014):
  • 7.4 asm 声明 [dcl.asm]
  • C++11 标准 (ISO/IEC 14882:2011):
  • 7.4 asm 声明 [dcl.asm]
  • C++03 标准 (ISO/IEC 14882:2003):
  • 7.4 asm 声明 [dcl.asm]
  • C++98 标准 (ISO/IEC 14882:1998):
  • 7.4 asm 声明 [dcl.asm]

参见

C 文档 关于 内联汇编

外部链接

1. GCC 内联汇编指南
2. GCC 内联汇编 — Locklessinc.com
3. IBM XL C/C++ 内联汇编
4. Intel C++ 内联汇编
5. Visual Studio 内联汇编器
6. Sun Studio 12 汇编语句
7. 基于 Itanium 的 HP-UX 内联汇编
8. X86 调用约定 — 维基百科