X86汇编与VS2008混合编程--仅供入门学习参考

22 篇文章 0 订阅
21 篇文章 0 订阅
                   X86汇编与VS2008混合编程--仅供入门学习参考
 
汇编文件保存为扩展名*.asm,
把汇编文件加入VS工程,点击文件右键,进入 编译选项 把属性中tool 选项 修改为Custom Build Tool
然后填写如下选项内容:
command line: yasm -I..\..\common\x86\ -f win32 -O2 -DPREFIX -o "$(IntDir)\$(InputName)".obj "$(InputPath)" 
outputes:  $(IntDir)\$(InputName).obj

A: 在C代码中调用汇编程序

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

 

global _add  ;全局函数声明,表示这个函数要被外部文件调用

_add:

 push ebp        ;保护ebp指针

 mov ebp,esp

 mov eax,[ebp+8] ;第一个入口参数int a

 mov ebx,[ebp+12];第二个入口参数int b

 add eax,ebx

 pop ebp         ;恢复ebp指针

 ret            ;调用者平衡堆栈


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

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

2.如果遵守stdcall 调用约定 FOR  C++

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

 

global _add@8  ;全局函数声明,表示这个函数要被外部文件调用

_add@8:

 push ebp        ;保护ebp指针

 mov ebp,esp

 mov eax,[ebp+8] ;第一个入口参数int a

 mov ebx,[ebp+12];第二个入口参数int b

 add eax,ebx

 pop ebp         ;恢复ebp指针

ret 8            ;被调用者平衡堆栈



 

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

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

这里要注意的是函数的名称问题,一般是_XXX@N ,也就是在开头加上一个下划线,@N中的N就是参数的大小。

B: 在汇编中调用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调用约定规定是调用者平衡堆栈.

;extern _myprint
global _myprint_asm
_myprint_asm:
	 push ebp        ;保护ebp指针
	 mov ebp,esp
	 mov eax,[ebp+8] ;第一个入口参数int VAR1
	 push eax       ;保护ebp指针	
	 call _myprint 
	 add esp ,4 调用了
	 pop ebp         ;恢复ebp指针
	 ret            ;调用者平衡堆栈

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了,有函数本身平衡堆栈.

extern _myprintstdcall@4
global _myprint_asm@4
_myprint_asm@4:
	 push ebp        ;保护ebp指针
	 mov ebp,esp
	 mov eax,[ebp+8] ;第一个入口参数int VAR1
	 push eax       ;保护ebp指针	
	 call _myprintstdcall@4 
	 pop ebp         ;恢复ebp指针
	 ret 4            ;调用者平衡堆栈


这个就是入门的学习,非常简单的环境学习X86汇编。

入门回了,后面就是开始学习X86的基本指令,调试,以及学习MMX,.SSE!

 

下面是一个最简单的例子: Hello world

 

data segment                            ;数据段开始
str db 'Hello world. ', '$ '            ;字符串声明,以字节的存储形式,以‘$’结尾  
data ends                               ;数据段结束  
code segment                            ;代码段开始  
assume cs:code,ds:data                  ;进行段的说明,说明一个对应的关系,之后再把段的首地址赋值给段寄存器,这样定义过的段才能被找到并被使用 
main:                                   ;程序代码段的开始标号  
mov ax,data                             ;段段寄存器不能直接赋值,用ax做桥梁  
mov ds,ax                               ;数据段寄存器
lea dx,str                              ;取str的有效地址
mov ah,09h                              ;中断调用入口参数  
int 21h                                 ;调用21h中断的09h号功能显示字符串
mov ah,4ch                              ;调用中断入口参数 
int 21h                                 ;调用21h中断的4ch功能功退出
code ends                               ;代码段结束  
end main                                ;程序结束


 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值