内联汇编
来自 cppreference.com
内联汇编(通常由 asm 关键字引入)能够在 C 程序中嵌入汇编语言源代码。
与 C++ 不同,内联汇编在 C 中被视为扩展。它是条件支持和实现定义的,这意味着它可能不存在,即使实现提供了它,它也没有固定的含义。
内容 |
[编辑] 语法
asm ( 字符串字面量 ) ; |
|||||||||
本节尚未完善 原因: 写一条关于 GCC 扩展汇编语法的说明,因为它现在被 Intel、IBM、Sun(从 v12 开始)等支持 |
[编辑] 解释
这种内联汇编语法被 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 内联汇编 |