内联汇编在现代C++中基本不可移植且不推荐使用,仅GCC在x86/x86_64平台较完整支持GNU风格语法;MSVC在x64下已完全移除支持,x86下也已弃用;执行机器码应通过mmap/VirtualAlloc分配可执行内存实现;多数场景应优先使用intrinsics、编译器优化提示或标准库原子操作替代。

内联汇编在现代 C++ 中基本不可移植、不推荐使用,且主流编译器(如 MSVC、Clang)对 asm 关键字的支持已严重受限或完全弃用。GCC 是目前唯一仍较完整支持 GNU 风格内联汇编的主流编译器,但仅限于 x86/x86_64 等特定目标平台。
GNU C 内联汇编语法(GCC / G++)
必须用 __asm__(或 asm)配合扩展语法,不能写裸机器码;所谓“嵌入机器指令”实际是让 GCC 生成对应指令,而非手动拼字节。
- 基本格式:
__asm__ volatile ("instruction" : outputs : inputs : clobbers) -
volatile防止被编译器优化掉(绝大多数情况都需要) - 输出操作数(如
"=r"(val))表示把寄存器结果写回变量val - 输入操作数(如
"r"(x))表示将x的值放入某个寄存器供指令使用 -
clobbers列出被修改但未声明为输出的寄存器(如"rax"、"cc"表示影响标志位)
int add_one(int x) {
int result;
__asm__ volatile ("addl $1, %0" : "=r"(result) : "0"(x));
return result;
}MSVC 不支持标准 asm 块(x64 下彻底移除)
MSVC 在 x64 编译模式下已完全删除内联汇编支持,连 __asm 关键字都会报错 C2400: inline assembler syntax error in 'first operand' 或直接 C4409: 'asm' is not supported on this architecture。
- x86(32 位)模式下仍支持
__asm块,但仅限于 MASM 语法,且不能用 C 变量名直接寻址(需通过mov eax, offset var等间接方式) - 无输出/输入约束机制,无法安全与 C 变量交互,极易因寄存器冲突或栈破坏导致崩溃
- Visual Studio 2019+ 对 x86 内联汇编也标记为 deprecated,不建议新项目使用
想执行任意机器码?别用 asm,改用运行时内存写入 + 执行
真正“嵌入机器指令字节”的做法是:分配可执行内存 → 写入 raw bytes → 强制跳转执行。但这属于平台敏感、安全敏感操作,需显式绕过 DEP/NX 保护。
立即学习“C++免费学习笔记(深入)”;
- Linux:用
mmap(..., PROT_READ | PROT_WRITE | PROT_EXEC, ...) - Windows:用
VirtualAlloc(..., PAGE_EXECUTE_READWRITE) - 必须禁用编译器栈保护(
-z execstack或/STACK:EXEC)和 ASLR(部分场景) - 函数指针类型需匹配调用约定(如
int (*f)() = (int(*)())code_buf;)
unsigned char code[] = { 0x89, 0xf8, 0xc3 }; // mov eax, edi; ret (x86-64 SysV)
void* exec_mem = mmap(nullptr, sizeof(code), PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
memcpy(exec_mem, code, sizeof(code));
int (*func)() = (int(*)())exec_mem;
int res = func(); // 执行
munmap(exec_mem, sizeof(code));替代方案比内联汇编更可靠
99% 的性能关键场景,应优先考虑编译器内置函数(intrinsics)或明确提示优化,而不是手写汇编。
- 用
__builtin_expect(GCC)、__assume(MSVC)做分支预测提示 - 用
_mm_add_epi32等 SSE/AVX intrinsic 替代手工向量化汇编 - 用
std::atomic替代::fetch_add lock xadd - 启用
-O2 -march=native让 GCC 自动向量化、内联、调度
手写汇编容易破坏编译器优化假设,反而降低性能;同时丧失跨平台能力,增加维护成本。除非你在写操作系统内核启动代码或极少数硬件驱动片段,否则不要碰它。










