随笔 - 8  文章 - 26  trackbacks - 0
<2009年4月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(4)

随笔档案

文章分类

文章档案

相册

C++语言

搜索

  •  

最新评论

阅读排行榜

评论排行榜



总结一下:

对于NASM与VC混合编程

在ASM文件的开头输入

[bits 32]                      ;使用32位模式的处理器

[section .text]                ;text段, 代码段,只读并可执行

声明代码段并且代码段是32位,应为对于VC生成的PE文件,其代码放在.text的代码段内

,数据放在.data的数据段内,所以如果要定义数据的话,要在.data段内

{一} 在C代码中调用汇编程序

1..如果遵守C 调用约定

打比方我们在ASM中实现两个数相加的函数:

_myadd:

push ebp

mov ebp,esp

mov eax,[ebp+8]  ;a

mov ebx,[ebp+12]    ;b

add eax,ebx

add esp,4

mov esp,ebp

pop ebp

ret 

在ASM的开头写上global _myadd;

在C文件中声明函数 extern "C" int _cdecl myadd(int a,int b); 

最主要的是要在ASM的函数名称的前面加上一个 _(下划线) ,但是在C文件中声明的函数不用加下划线,并且一定要加上extern "C",并且用_cdecl 声明,这样以后就可以在C中调用ASM中的函数了。

2.如果遵守stdcall 调用约定

还用上面的那个两个数相加的例子

_myaddstdcall@8:

push ebp

mov ebp,esp

mov eax,[ebp+8]  ;a

mov ebx,[ebp+12]    ;b

add eax,ebx

add esp,4

mov esp,ebp

pop ebp

ret 8

在ASM文件的开头写上 global _myaddstdcall@8

在C文件中声明函数 extern "C" int _stdcall myaddstdcall(int a,int b); 

这里要注意的是函数的名称问题,一般是_XXX@N ,也就是在开头加上一个下划线,@N中的N跟参数的大小有关系,目前我的理解是所有参数在堆栈中占用的总的大小.但是不确定,我只是推测的,如果那位知道具体的规定一定要告我一声啊。

{二} 在汇编中调用C中的函数

1.遵守C调用约定

举个例子:

extern "C" void _cdecl myprint(int a)

{

printf("myprint %d\n",a);

}

在ASM中声明 extern _myprint ,然后就可以用 push xxx ,call myprint   , add esp ,4 调用了

。要注意的是call 调用完后,一定要加上add esp ,X 来平衡堆栈,应为C调用约定规定是调用者平衡堆栈.

2.遵守stdcall 调用约定

extern "C" void _stdcall  myprintstdcall(int a)

{

printf("myprintstdcall %d\n",a);

}

在ASM中声明extern _myprintstdcall@4 ,然后用push xxx  ,call _myprintstdcall@4 调动,这里就不用再加add esp,X了,有函数本身平衡堆栈.

就这些了,都是个人总结,难免有不足与错误,还请大家指正.

posted on 2009-04-07 22:53 杨彬彬 阅读(3823) 评论(1)  编辑 收藏 引用

FeedBack:
# re: NASM 与 VC 混合编程的小结 2011-04-26 14:25 5545645
收下了  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理