如何将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
相关产品推荐
相关产品推荐

