汇编与C/C++混合编程练习

1 分别用嵌入式汇编方法和模块连接的方法实现求n个元素数组中的最小数的函数

1.1 嵌入式汇编

在C/C++语言中直接使用汇编语言语句,函数中用汇编实现功能

// c_main.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <bits/stdc++.h>
using namespace std;

int min_num2(int n, int* array)
{
   __asm
  {
       mov ecx, n
       mov edi, 0
       mov edx, array
       mov eax, [edx + edi * 4]
       L1:
       cmp eax, [edx + edi * 4]
       jb L2
       mov eax, [edx + edi * 4]
       L2:
       inc edi
       loop L1
  }
}

int main()
{
   int n = 0;
   int array[100] = {0};
   printf("数组元素个数:\n");
   scanf_s("%d", &n);
   printf("它们分别是:\n");
   for(int i = 0; i < n; i++)
  {
       scanf_s("%d", &array[i]);
  }
   int r = min_num2(n, array);
   printf("最小数是:%d\n",r);
   return 0;
}

开始没有注意到嵌入式汇编不可以使用宏,因此我使用了高级语言特性的循环与判断,报错内联错误

 

运行结果为:

img

1.2 模块连接

汇编模块写在.asm里,设置其属性

img

img

cpp文件:

// c_main.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <bits/stdc++.h>
using namespace std;

extern "C" {
   int min_num(int n, int* array);
}

int main()
{
   int n = 0;
   int array[100] = {0};
   printf("数组元素个数:\n");
   scanf_s("%d", &n);
   printf("它们分别是:\n");
   for(int i = 0; i < n; i++)
  {
       scanf_s("%d", &array[i]);
  }
   int r = min_num(n, array);
   printf("最小数是:%d\n",r);
   return 0;
}

asm文件:

    .386
.model flat, c

min_num proto C, n:dword, array:ptr dword

.code
min_num proc C, n:dword, array:ptr dword
mov esi,n
mov edx,array
mov eax,[edx]
.while esi>0
dec esi
mov ebx,[edx]
.if eax>[edx]
mov eax,[edx]
.endif
add edx,4
.endw
ret
min_num endp
end

这里面有问题,如果我直接在asm里对传入的参数array进行运算,则一定会出错,必须将其存入寄存器中

 

运行结果为

img

2 用C/C++实现求n个元素数组中的最小数的函数

利用函数即可

// c_main.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <bits/stdc++.h>
using namespace std;

int min_num3(int n, int* array)
{
   return *min_element(array, array + n);
}

int main()
{
   int n = 0;
   int array[100] = {0};
   printf("数组元素个数:\n");
   scanf_s("%d", &n);
   printf("它们分别是:\n");
   for(int i = 0; i < n; i++)
  {
       scanf_s("%d", &array[i]);
  }
   int r3 = min_num3(n, array);
   printf("最小数是:%d\n",r3);
   return 0;
}

3 分别与嵌入式汇编、模块连接方法进行比较,测试优化效果

导入老师给的时间记录头文件

#include <stdint.h>

uint64_t get_clock()
{
uint32_t high32 = 0;
uint32_t low32 = 0;
uint64_t r = 0;

__asm
{
rdtsc
mov high32, edx
mov low32, eax
};
r = (uint64_t)high32;
r <<= 32;
r += low32;
return r;
}

给出测试代码

// c_main.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <bits/stdc++.h>
#include "t.h"
using namespace std;

extern "C" {
   int min_num1(int n, int* array);
}

int min_num2(int n, int* array)
{
   __asm
  {
       mov ecx, n
       mov edi, 0
       mov edx, array
       mov eax, [edx + edi * 4]
       L1:
       cmp eax, [edx + edi * 4]
       jb L2
       mov eax, [edx + edi * 4]
       L2:
       inc edi
       loop L1
  }
}

int min_num3(int n, int* array)
{
   return *min_element(array, array + n);
}

int array[100000000] = { 0 };

int main()
{
   int n = 0;
   printf("数组元素个数:\n");
   scanf_s("%d", &n);
   srand((unsigned)time(NULL));
   for(int i = 0; i < n; i++)
  {
      ::array[i]= rand() % 1000;
  }
   int t1 = get_clock();
   int r1 = min_num1(n, ::array);
   int t2 = get_clock();
   

   int r2 = min_num2(n, ::array);
   int t3 = get_clock();
   

   int r3 = min_num3(n, ::array);
   int t4 = get_clock();
   printf("模块链接时间为:%d\n", t2 - t1);
   printf("嵌入式编程时间为:%d\n", t3 - t2);
   printf("C++函数调用时间为:%d\n", t4 - t3);

   printf("最小数是:%d,%d,%d\n",r1,r2,r3);
   return 0;
}

在数组元素为10000时:

img

在数组元素为1000000时:

img

在数组元素为100000000时:

img

很明显可以看出,优化性能:模块连接>嵌入式汇编>C++函数

汇编语言在性能优化方面有着很好的效果,尤其是在模块连接时

 

posted @ 2022-04-10 01:18  Xiaohanahahah  阅读(369)  评论(0编辑  收藏  举报