// 我的家:http://alphasun.betajin.com/
汇编的程序往往不是独立编写使用的,它经常被其它高级语言调用。 在开发中需要高速的代码的时候,我就会把他做成汇编的子程序,然 后让VC的程序来调用。 在WIN32平台上的汇编的编写使用的模式不同于DOS,在DOS上写程序 往往使用small、large 等模式,但是在WIN32上一定要使用flat模式。 也就是说需要在源文件中定义.model flat。 在老式的C上,函数名汇编成 _func() 这样的形式,但是C++就没有那 么简单了。C++的目标代码中的函数名与源代码中的函数名非常的不同。 所以需要在使用汇编子程序的时候用 extern "C"指明这个按照C的习惯 来编译。
下面这个例子是用qsort()对整数数组进行排序,CompInt()使用汇编 写的比较两个数据大小的回调函数。CompInt1()使用C++写的。大家 可以比较一下这两个函数的速度上的差异。
汇编部分的编译方法,形成.obj文件后把它加入到你的VC工程中去。 ml /c XXX.asm
//####################################################################### // VC代码部分 #include "stdafx.h" #include <windows.h> #include "stdio.h" #include <stdlib.h>
// 汇编自函数的原型声明 extern "C" int CompInt(const void*, const void*);
void OutInt(int x, int y) { printf("%d %d\n", x, y); }
int CompInt1(const void *p1, const void *p2) { if(*(int*)p1 > *(int*)p2) return 1; else if(*(int*)p1 < *(int*)p2) return -1; else return 0; }
#define SIZE (1024*1024) int a[SIZE]; LARGE_INTEGER t0, t1, f; void main() { int i;
srand(102344); for(i=0; i<SIZE; i++) { a[i] = rand()*10*SIZE/RAND_MAX; } printf("\n"); puts("sorting...");
QueryPerformanceFrequency(&f); QueryPerformanceCounter(&t0);
qsort(a, SIZE, sizeof(int), CompInt); printf("------------------------complete\n");
QueryPerformanceCounter(&t1); printf("t = %lf\n", (double)(t1.QuadPart-t0.QuadPart)/((double)(f.QuadPart))); }
################################################################################################# // 汇编代码部分 .586 .MODEL FLAT
_OutInt PROTO NEAR32, .CODE
_CompInt PROC push ebx; push ecx; mov ecx, [esp+12]; // 取参数 mov eax, [ecx]; mov ecx, [esp+16]; mov ebx, [ecx] ; push eax; // 调用C中的子函数,还没有在C++上面试通 ; push ebx; // 另外,我发现C的函数不会保护寄存器,很奇怪 ; push eax; // 所以要自己保护寄存器 ; push ebx; ; call _OutInt; ; add esp, 8 ; pop ebx; ; pop eax; cmp eax, ebx; // 比较,分三种情况返回 jc l_c; jz l_z; mov eax, 1 pop ecx; pop ebx ret ; // a>b 返回 l_z: mov eax, 0; // 相等 pop ecx; // 清零的方法比较傻,请勿耻笑 pop ebx ret l_c: mov eax, 0ffffffffh; // a < b pop ecx; pop ebx ret _CompInt ENDP END

|