VC连接调用MASM32编译的obj文件
汇编例子:
.386
.modelflat, stdcall
optioncasemap :none ; case sensitive
.code
_add proc inta,intb
;pushebp
;movebp,esp
moveax,[ebp+8]
movebx,[ebp+12]
addeax,ebx
ret
_add endp
end
说明:不需要 push ebp,mov ebp,esp这两句,vc编译连接时会自动添加
ret指令不需要弹出参数,调用者会清理堆栈
_add函数要在最后写入end伪指令,结束该asm模块,使之能够单独编译。end指令在程序项目中是用于指定入口点的,该库文件不能指定入口点,因为这不是主程序,所以直接写end即可.
编译指令:ml /c /coff add.asm(这里假设文件名为add.asm)
vc部分:新建一个简单的控制台hello world例子
#include "stdafx.h"
extern "C" int __stdcall _add(int,int);
int main(int argc, char* argv[])
{
int a;
printf("HelloWorld!\n");
a=_add(1,2);
printf("ssss%d",a);
return 0;
}
说明:被调用的函数声明必须加上extern"C",这里的C告诉编译器这个外部函数的修饰名使用C语言的修饰规则而不是C++语言,
__stdcall
这里前面是两个下滑划线,这是C++语言中指定函数调用规则的关键字,这里使用stdcall调用规则,因为原来的汇编代码中的指令.model flat,stdcall,指定了函数的调用规则,所以这里要一致,否则就会出现堆栈错误。程序就挂了。。。
vc6编译选项设置:Project->Settings->link->Object/Library modules:下面的框框后面追加汇编编译的obj文件名:add.obj如果是放在vc工程目录的debug文件夹里要带上路径debug\add.obj,
或者把obj拷入debug文件夹,然后在文件头部加入一句:
#pragma comment(lib,"debug\YourObjName.obj ")
编译连接,OK,如果程序出现错误,要用ollydbg或其他工具查看_add函数调用前后堆栈是否平衡。
(完)