You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Visual Studio的__asm{}汇编代码转为GCC的__asm__()格式

VS __asm转g++ __asm__崩溃问题

我是汇编纯新手,完全没基础。之前在Visual Studio里能正常跑的代码,现在需要用g++ -o fileName.o filename.cpp编译成.o文件,得把VS里用花括号的__asm改成g++的圆括号__asm__格式,但编译后运行崩溃,编译器还提示要用(替代{。

原VS可运行代码:

unsigned char decode5a[0x0dac];
unsigned char* srcbuf = new unsigned char[4000];
m_image = new unsigned char[4000];
unsigned char* dstbuf = m_image;

__asm
{
     lea eax, decode5a
     push srcbuf
     push dstbuf
     call eax
     add esp, 8
}

我自己改成下面这样还是崩溃,感觉是变量传递的方式错了:

__asm__(
     "lea eax, decode5a \n
     push srcbuf \n
     push dstbuf \n
     call eax \n
     add esp, 8 \n
");

解决方法

GNU内联汇编和VS的__asm语法差很多,直接写C++变量名汇编根本认不出来,得用扩展汇编的约束机制让编译器处理变量寻址。正确的改写如下:

__asm__ volatile (
    "lea eax, %[decoder]\n\t"
    "push %[src]\n\t"
    "push %[dst]\n\t"
    "call eax\n\t"
    "add esp, 8"
    :  // 无输出参数,留空
    : [decoder] "m" (decode5a), [src] "r" (srcbuf), [dst] "r" (dstbuf)
    : "eax", "esp", "memory"  // 声明被修改的寄存器和内存
);

关键说明:

  • 用%[别名]来引用C++变量,后面的约束段[别名] "约束符" (变量名)告诉编译器怎么处理这个变量:"m"表示变量在内存,"r"表示用寄存器存变量
  • volatile防止编译器把这段汇编优化掉
  • 破坏描述必须声明被修改的寄存器(eax、esp)和内存,避免编译器优化出问题

另外要注意:

  • 确保decode5a里是正确的x86机器码函数,且调用约定是cdecl(手动add esp,8符合这个约定)
  • 如果是64位系统编译,必须加-m32参数切换到32位模式,否则x86_64的调用约定完全不同,代码必然崩溃:g++ -m32 -o fileName.o filename.cpp

内容的提问来源于stack exchange,提问作者BiggestUbuntuNoobie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 21:35:14