VS2010中内联汇编入门--cdecl
2013-08-20 17:45
239 查看
在vs2010中进行内联汇编时,注意在被调函数中,编译器自动在栈中为局部变量预留一个区域,如下面的反汇编代码所示,ebp-0xc0,并且初始化为0xcccccccc
参数传递:
在cdecl调用下,参数由上层调用函数进行入栈,在内联汇编模式下,访问参数要用中括号加参数名称的方式获取参数
不要使用下面的方式:
这种方式在DEBUG下是正确的,但是在Release下会报错
下面是一个求MSE的小函数
完整的代码:
【资料】比较好的说明: http://blog.csdn.net/kzh313561014/article/details/7283765
【GGC 下的 at&t 汇编】http://blog.csdn.net/zhangqingsup/article/details/6704253
int __cdecl mse_sse(unsigned char * a, unsigned char * b, int len){ 00B213B0 push ebp 00B213B1 mov ebp,esp 00B213B3 sub esp,0C0h 00B213B9 push ebx 00B213BA push esi 00B213BB push edi 00B213BC lea edi,[ebp-0C0h] 00B213C2 mov ecx,30h 00B213C7 mov eax,0CCCCCCCCh 00B213CC rep stos dword ptr es:[edi]
参数传递:
在cdecl调用下,参数由上层调用函数进行入栈,在内联汇编模式下,访问参数要用中括号加参数名称的方式获取参数
mov esi,[a];//a 00B213CE mov esi,dword ptr [a] mov edi,[b];//b 00B213D1 mov edi,dword ptr [b] mov ecx,[len];//len 00B213D4 mov ecx,dword ptr [len]
不要使用下面的方式:
mov esi,[ebp+8];//a mov edi,[ebp+8+4];//b mov ecx,[ebp+8+8];//len
这种方式在DEBUG下是正确的,但是在Release下会报错
下面是一个求MSE的小函数
int __cdecl mse_sse(unsigned char * a, unsigned char * b, int len){ __asm{ /* mov esi,[ebp+8];//a mov edi,[ebp+8+4];//b mov ecx,[ebp+8+8];//len */ mov esi,[a];//a mov edi,[b];//b mov ecx,[len];//len pxor xmm7,xmm7;//128bit 0 movdqu xmm0,[esi];//a[0-7] punpcklbw xmm0,xmm7;//8bit->16bit movdqu xmm1,[edi];//b[0-7] punpcklbw xmm1,xmm7;//8bit->16bit psubw xmm0,xmm1;//a-b pabsw xmm0,xmm0; //|a-b| //movdqu [esi],xmm0 pmullw xmm0,xmm0;//|a-b|^2 phaddw xmm0,xmm0;//0,1->0 phaddw xmm0,xmm0;//0,1,2,3->0 phaddw xmm0,xmm0;//0,...,7->0 movd eax,xmm0; } }
完整的代码:
//fiel:main.c #include<stdlib.h> #include<stdio.h> #include"mem_align.h" #include "asm.h" struct sByte{ char c; int i; } aa; int main(int argc, char * argv[]) { int size =30; int align_size =16; //unsigned char * pVar_mem=(unsigned char *)(malloc(size+align_size));\ //unsigned char * pVar = pVar_mem+(align_size-(int)pVar_mem&0xf); align_mem_get(pBuffer,30,16); struct sByte bb; unsigned char a[32]={0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7}; unsigned char b[32]={0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7}; int len = 8; int mse=mse_sse_v2(a,b,len); printf("mse = : %d \n",mse); mse=mse_sse(a,b,len); printf("mse = : %d \n",mse); printf("%d \n",sizeof(aa)); printf("%d \n",sizeof(bb)); printf("align_mem_get pBuffer : 0x%08x \n",(int)pBuffer); printf("align_mem_get pBuffer : 0x%08x mod 16 = %d \n",(int)pBuffer,(int)pBuffer%16); align_mem_free(pBuffer); return 0; }
/* FILE: mem_align.h */ #ifndef _MEM_AQLIGN_H_ #define _MEM_AQLIGN_H_ #define align_mem_get(pVar,size,align_size)\ unsigned char * pVar_mem=(unsigned char *)(malloc(size+align_size));\ unsigned char * pVar = pVar_mem+(align_size-(int)pVar_mem&0xf) #define align_mem_free(pVar) \ free(pVar_mem); \ pVar = 0 #endif
// asm.h #ifndef _ASM_H_ #define _ASM_H_ #include <xmmintrin.h>//SSE #include <emmintrin.h>//SSE2 #include <pmmintrin.h>//SSE3 #include <tmmintrin.h>//SSSE3 #include <smmintrin.h>//SSE4.1 #include <nmmintrin.h>//SSE4.2 #include <immintrin.h>//AVX,AVX2,FMA //__declspec(naked) static int mse_sse(unsigned char * a, unsigned char * b, int len); int __cdecl mse_sse(unsigned char * a, unsigned char * b, int len); int __cdecl mse_sse_v2(unsigned char * a, unsigned char * b, int len); #endif
//file:asm.c
#include "asm.h"
//8x8 16bit unsigned short
//int __stdcall mse_sse(unsigned char * a, unsigned char * b, int len){
//__declspec(naked) static int mse_sse(unsigned char * a, unsigned char * b, int len){
int __cdecl mse_sse(unsigned char * a, unsigned char * b, int len){ __asm{ /* mov esi,[ebp+8];//a mov edi,[ebp+8+4];//b mov ecx,[ebp+8+8];//len */ mov esi,[a];//a mov edi,[b];//b mov ecx,[len];//len pxor xmm7,xmm7;//128bit 0 movdqu xmm0,[esi];//a[0-7] punpcklbw xmm0,xmm7;//8bit->16bit movdqu xmm1,[edi];//b[0-7] punpcklbw xmm1,xmm7;//8bit->16bit psubw xmm0,xmm1;//a-b pabsw xmm0,xmm0; //|a-b| //movdqu [esi],xmm0 pmullw xmm0,xmm0;//|a-b|^2 phaddw xmm0,xmm0;//0,1->0 phaddw xmm0,xmm0;//0,1,2,3->0 phaddw xmm0,xmm0;//0,...,7->0 movd eax,xmm0; } }
int __cdecl mse_sse_v2(unsigned char * a, unsigned char * b, int len){
int x = (int)a;
return len;
}
【资料】比较好的说明: http://blog.csdn.net/kzh313561014/article/details/7283765
【GGC 下的 at&t 汇编】http://blog.csdn.net/zhangqingsup/article/details/6704253
相关文章推荐
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
- VS2010/MFC编程入门之二十六(常用控件:滚动条控件Scroll Bar)
- VS2010/MFC编程入门之前言
- VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
- VS2010/MFC编程入门之十五(对话框:消息对话框)
- VS2010/MFC编程入门之五十二(Ribbon界面开发:创建Ribbon样式的应用程序框架)
- (转载)VS2010/MFC编程入门之五(MFC消息映射机制概述)
- OpenGL学习入门之VS2010环境配置 [转]
- VS2010/MFC编程入门教程之目录和总结
- C#创建Windows服务入门图解(VS2010)
- (转载)VS2010/MFC编程入门之三十七(工具栏:工具栏的创建、停靠与使用)
- (转载)VS2010/MFC编程入门之五十(图形图像:GDI对象之画笔CPen)
- VS2010/MFC编程入门之三十八(状态栏的使用详解)
- VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口)
- VS2010/MFC编程入门之四(MFC应用程序框架分析)
- VS2010/MFC编程入门之七(对话框:为对话框添加控件)
- 【OpenCV入门教程之一】 OpenCV 2.4.8 +VS2010的开发环境配置
- VS2010/MFC编程入门之二(利用MFC向导生成单文档应用程序框架)
- VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
- VS2010/MFC编程入门之十七(对话框:字体对话框)