C++嵌入汇编语言计算有符号数组的平均值

  • 2019 年 11 月 7 日
  • 笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/weixin_42449444/article/details/102556037

关于嵌入汇编:

嵌入汇编是指在C和C++的源程序中插入汇编语言指令,也称内嵌汇编、内联汇编或行内汇编。VisualC++中使用“__asm”关键字指示嵌入汇编,不需要独立的汇编系统就可以正常编译和连接。使用“__asm”关键字既可以引导单条回汇编语言指令,也可以用空格在同一行分隔多个“__asm”引导的汇编语言指令,更好的方法是使用花括号书写一个汇编语言程序片段。

VC++6.0支持通用整数和浮点指令集以及MMX指令集的嵌入汇编。对于还不能支持的指令,VC++提供了_emit伪指令进行拓展。嵌入汇编语言代码可以使用C++的数据类型和数据对象,也可以使用MASM的表达式和注释风格,但不可以使用MASM的绝大多数伪指令和宏汇编方法。

在VC++中使用嵌入汇编还需要注意一些具体的规定。例如,在汇编语言编写的函数中,不必保存EAX、EBX、ECX、EDX、ESI和EDI寄存器,但必须保存函数中使用的其它寄存器(如ESP、EBP和整数标志寄存器等)。嵌入式汇编语言语句中,可以使用汇编语言格式表示整数常量(如378H),也可以使用C++的格式来进行表示(如0x378)。嵌入式汇编中的标号和C++的标号相似,它的作用是在定义它的函数中有效。

在VC++集成开发环境中,建立一个win32控制台程序的项目,输入源代码后进行编译连接就可以产生一个可执行文件。需要注意的是:debug活动解决方案平台一定要选X86!不能够X64!不然编译器会报错。

计算有符号数组的平均值:

#include <iostream>  using namespace std;  #define Up(i,a,b) for(int i = a; i <= b; i++)  const int maxn = 1005;  int getAvg(int d[], int n,int* m);    //嵌入汇编语言来计算有符号数平均值    int main()  {      ios::sync_with_stdio(false);      cin.tie(0), cout.tie(0);      int d[maxn];      int n;    //数组大小n      cin >> n;      Up(i, 0, n - 1)      {          cin >> d[i];      }      int* m = new int;   //余数m      int avg = getAvg(d, n,m);   //商      cout << "平均值是:" << avg << endl;      if (*m != 0)      {          cout << "余数是:" << *m << endl;      }      delete m;   //删除指针并置为空      m = NULL;      return 0;  }    int getAvg(int d[], int n,int* m)  {      int avg,rmd;   //平均值avg,余数rmd      __asm   //嵌入汇编代码      {          mov ebx, d        //EBX=数组地址          mov ecx, n        //ECX=数据个数          xor eax, eax      //EAX保存和,先清零          xor edx, edx      //EDX=当前指向数组元素的下标          getsum :          //循环求数组和          add eax, [ebx + edx * 4]              add edx, 1    //指向下一地址              cmp edx, ecx  //比较当前下标是否小于数据个数n              jb getsum     //继续循环              cdq           //将累加和EAX符号扩展到EDX          idiv ecx      //有符号除法,EAX=商,EDX=余数          mov avg, eax  //将EAX的值赋给avg          mov rmd,edx    //将EDX的值赋给*m      }      *m = rmd;    //直接mov *m,edx会有内联汇编语法错误      return avg;  }