《汇编语言 基于x86处理器》第十三章高级语言接口部分的代码 part 1

? 书中第十三章的程序,主要讲了汇编语言和 C/++ 相互调用的方法

● 代码,数组求和的几种优化

 1 int arraySum(int array[], int count)            ; O0
 2 {
 3 010716D0  push        ebp
 4 010716D1  mov         ebp,esp
 5 010716D3  sub         esp,0D8h
 6 010716D9  push        ebx
 7 010716DA  push        esi
 8 010716DB  push        edi
 9 010716DC  lea         edi,[ebp-0D8h]
10 010716E2  mov         ecx,36h
11 010716E7  mov         eax,0CCCCCCCCh
12 010716EC  rep stos    dword ptr es:[edi]        ; 栈顶
13     int i;
14     int sum = 0;
15 010716EE  mov         dword ptr [sum],0
16
17     for (i = 0; i < count; i++)
18 010716F5  mov         dword ptr [i],0
19 010716FC  jmp         arraySum+37h (01071707h)  ; 跳转循环判断
20 010716FE  mov         eax,dword ptr [i]         ; ┓
21 01071701  add         eax,1                     ; ┣ 取出 i 来加一再放回去
22 01071704  mov         dword ptr [i],eax         ; ┛
23 01071707  mov         eax,dword ptr [i]         ; ┓
24 0107170A  cmp         eax,dword ptr [count]     ; ┣ 循环判断
25 0107170D  jge         arraySum+50h (01071720h)  ; ┛
26         sum += array[i];
27 0107170F  mov         eax,dword ptr [i]         ; 循环主体,各变量取出来,加完了 sum 放回去
28 01071712  mov         ecx,dword ptr [array]
29 01071715  mov         edx,dword ptr [sum]
30 01071718  add         edx,dword ptr [ecx+eax*4]
31 0107171B  mov         dword ptr [sum],edx
32 0107171E  jmp         arraySum+2Eh (010716FEh)
33
34     return sum;
35 01071720  mov         eax,dword ptr [sum]       ; 返回值放入 eax
36 }
37 01071723  pop         edi
38 01071724  pop         esi
39 01071725  pop         ebx
40 01071726  mov         esp,ebp
41 01071728  pop         ebp
42 01071729  ret 
 1 int arraySum(int array[], int count)            ; O1
 2 {
 3 00E51743  push        ebp                       ; 优化了寄存器和栈
 4 00E51744  mov         ebp,esp
 5     int i;
 6     int sum = 0;
 7 00E51746  xor         eax,eax
 8 00E51748  mov         ecx,eax                   ; ecx 存储 i
 9
10     for (i = 0; i < count; i++)
11 00E5174A  cmp         dword ptr [count],eax     ; ┳ 数组长 <0 则退出
12 00E5174D  jle         arraySum+18h (0E5175Bh)   ; ┛
13 00E5174F  mov         edx,dword ptr [array]     ; ┓
14         sum += array[i];                        ; ┣ 循环主体
15 00E51752  add         eax,dword ptr [edx+ecx*4] ; ┛
16 00E51755  inc         ecx                       ; ┓
17 00E51756  cmp         ecx,dword ptr [count]     ; ┣ i++ 和循环判断
18 00E51759  jl          arraySum+0Fh (0E51752h)   ; ┛
19
20     return sum;
21 }
22 00E5175B  pop         ebp
23 00E5175C  ret
24     int array[10] = { 1,2,3,4,5,6,7,8,9,10 };   ; 主函数的部分
25
26     int sum = arraySum(array, 10);
27     return 0;
28     00E5175D  xor         eax,eax
29 }
30 00E5175F  ret
 1 int arraySum(int array[], int count)            ; O2 / Ox,用了XMM,没啃完
 2 {
 3 000E1760  push        ebp
 4 000E1761  mov         ebp,esp
 5 000E1763  push        ecx
 6
 7     for (i = 0; i < count; i++)
 8 000E1764  mov         edx,dword ptr [array]
 9 000E1767  xor         ecx,ecx
10 000E1769  push        ebx
11 000E176A  push        esi
12 000E176B  mov         esi,dword ptr [count]
13 000E176E  xor         eax,eax
14 000E1770  mov         dword ptr [ebp-4],ecx
15 000E1773  push        edi
16 000E1774  test        esi,esi
17 000E1776  jle         arraySum+7Bh (0E17DBh)
18 000E1778  cmp         esi,8
19 000E177B  jb          arraySum+7Bh (0E17DBh)
20     int i;
21     int sum = 0;
22 000E177D  mov         ecx,esi
23 000E177F  and         ecx,80000007h
24 000E1785  jns         arraySum+2Ch (0E178Ch)
25 000E1787  dec         ecx
26 000E1788  or          ecx,0FFFFFFF8h
27 000E178B  inc         ecx
28 000E178C  mov         edi,esi
29 000E178E  xorps       xmm2,xmm2
30 000E1791  sub         edi,ecx
31 000E1793  xorps       xmm1,xmm1
32 000E1796  nop         word ptr [eax+eax]
33         sum += array[i];
34 000E17A0  movups      xmm0,xmmword ptr [edx+eax*4]
35 000E17A4  paddd       xmm2,xmm0
36 000E17A8  movups      xmm0,xmmword ptr [edx+eax*4+10h]
37 000E17AD  add         eax,8
38 000E17B0  paddd       xmm1,xmm0
39 000E17B4  cmp         eax,edi
40 000E17B6  jl          arraySum+40h (0E17A0h)
41     int i;
42     int sum = 0;
43 000E17B8  paddd       xmm1,xmm2
44 000E17BC  movaps      xmm0,xmm1
45 000E17BF  psrldq      xmm0,8
46 000E17C4  paddd       xmm1,xmm0
47 000E17C8  movups      xmm0,xmm1
48 000E17CB  psrldq      xmm0,4
49 000E17D0  paddd       xmm1,xmm0
50 000E17D4  movd        ecx,xmm1
51 000E17D8  mov         dword ptr [sum],ecx
52
53     for (i = 0; i < count; i++)
54 000E17DB  xor         edi,edi
55 000E17DD  xor         ebx,ebx
56 000E17DF  cmp         eax,esi
57 000E17E1  jge         arraySum+0B4h (0E1814h)
58 000E17E3  mov         ecx,esi
59 000E17E5  sub         ecx,eax
60 000E17E7  cmp         ecx,2
61 000E17EA  jl          arraySum+9Eh (0E17FEh)
62 000E17EC  lea         ecx,[esi-1]
63 000E17EF  nop
64         sum += array[i];
65 000E17F0  add         edi,dword ptr [edx+eax*4]
66 000E17F3  add         ebx,dword ptr [edx+eax*4+4]
67 000E17F7  add         eax,2
68 000E17FA  cmp         eax,ecx
69 000E17FC  jl          arraySum+90h (0E17F0h)
70
71     for (i = 0; i < count; i++)
72 000E17FE  cmp         eax,esi
73         sum += array[i];
74 000E1800  mov         esi,dword ptr [sum]
75 000E1803  jge         arraySum+0A8h (0E1808h)
76 000E1805  add         esi,dword ptr [edx+eax*4]
77 000E1808  lea         eax,[ebx+edi]
78 000E180B  pop         edi
79 000E180C  add         eax,esi
80
81     return sum;
82 }
83 000E180E  pop         esi
84 000E180F  pop         ebx
85 000E1810  mov         esp,ebp
86 000E1812  pop         ebp
87 000E1813  ret
88 000E1814  pop         edi
89 000E1815  pop         esi
90 000E1816  mov         eax,ecx
91 000E1818  pop         ebx
92 000E1819  mov         esp,ebp
93 000E181B  pop         ebp
94 000E181C  ret 

● C 内嵌汇编(代码段),检查对象大小

 1 #include <iostream>
 2
 3 #pragma warning (disable:4101)  // 关闭警告 "unreferenced local variables"
 4
 5 int main()
 6 {
 7     struct Package
 8     {
 9         int     intInStruct;            // 4
10         float   floatInStruct;          // 4
11         long    doubleInStruct;         // 4
12     } myPackage;
13
14     char        myChar;
15     bool        myBool;
16     short       myShort;
17     int         myInt;
18     long        myLong;
19     float       myFloat;
20     double      myDouble;
21     long double myLongDouble;
22     long        myLongArray[10];
23
24     __asm                               // 内联汇编代码
25     {
26         mov  eax, myPackage.doubleInStruct;// 地址
27
28         mov  eax, LENGTH myInt;         // 1
29         mov  eax, LENGTH myLongArray;   // 10
30
31         mov  eax, TYPE myChar;          // 1
32         mov  eax, TYPE myBool;          // 1
33         mov  eax, TYPE myShort;         // 2
34         mov  eax, TYPE myInt;           // 4
35         mov  eax, TYPE myLong;          // 4
36         mov  eax, TYPE myFloat;         // 4
37         mov  eax, TYPE myDouble;        // 8
38         mov  eax, TYPE myLongDouble;    // 8
39
40         mov  eax, TYPE myPackage;       // 12
41         mov  eax, TYPE myLongArray;     // 4
42
43         mov  eax, LENGTH myPackage;     // 1
44         mov  eax, LENGTH myLongArray;   // 10
45
46         mov  eax, SIZE myPackage;       // 12,SIZE 返回 LENGTH * TYPE
47         mov  eax, SIZE myLongArray;     // 40
48     }
49     return 0;
50 }

● C++ 内嵌汇编(单独的函数),加密字符串

 1 #include <iostream>
 2 #include <string>
 3
 4 using namespace std;
 5
 6 void TranslateBuffer(char * buf, unsigned count, unsigned char eChar)
 7 {
 8     __asm
 9     {
10         mov esi, buf    // esi 指向待处理的内存
11         mov ecx, count
12         mov al, eChar
13     L1:
14         xor[esi], al
15         inc  esi
16         Loop L1
17     }
18 }
19
20 int main(int argcount, char * args[])
21 {
22     string buffer;
23     unsigned char encryptCode;
24
25     cout << "Input the string:\n\t";            // 需要加密的字符串
26     cin >> buffer;
27     cout << "\nEncryption code [0-255]?\n\t";   // 秘钥
28     cin >> encryptCode;
29
30     TranslateBuffer(&buffer[0], buffer.length(), encryptCode);
31
32     cout << "Output:\n\t" << buffer;
33     getchar();
34     getchar();
35     return 0;
36 }

● C++ 内嵌汇编(独立文件),线性查找。要点:单独使用 ml.exe 编译 index2.asm 生成 index2.obj,在工程中添加为资源文件。输出结果:没开优化,效率奇低(C++ 7193 ms,ASM 34852 ms)

1 // index.h
2 extern "C"
3 {
4     long index( long n, unsigned array[], unsigned count);
5     long index2(long n, unsigned array[], unsigned count);
6 }
 1 // index.cpp
 2 #include "index.h"
 3
 4 long index(long searchVal, unsigned array[], unsigned count)
 5 {
 6     for (unsigned i = 0; i < count; i++)
 7     {
 8         if (array[i] == searchVal)
 9             return i;
10     }
11     return -1;
12 }
 1 ; index2.asm
 2 .586
 3 .model flat, C
 4 index2 PROTO, srchVal:DWORD, arrayPtr:PTR DWORD, count:DWORD
 5
 6 .code
 7
 8 index2 PROC uses ecx esi edi, srchVal:DWORD, arrayPtr:PTR DWORD, count:DWORD
 9     NOT_FOUND = -1
10
11     mov     eax, srchVal    ; 目标值
12     mov     ecx, count
13     mov     esi, arrayPtr
14     mov     edi, 0          ; 数组下标
15
16 L1:
17     cmp     [esi + edi * 4], eax
18     je      found
19     inc     edi
20     loop L1
21
22 notFound:
23      mov    eax, NOT_FOUND
24      jmp    short exit
25
26 found:
27      mov    eax, edi
28
29 exit:
30      ret
31 index2 ENDP
32 END
 1 // main.cpp
 2 #include <iostream>
 3 #include <time.h>
 4 #include "index.h"
 5
 6 using namespace std;
 7
 8 int main()
 9 {
10     const unsigned ARRAY_SIZE = 100000, LOOP_SIZE = 1000000;    // 数组大小和重复次数
11     const unsigned searchVal = rand();
12     clock_t startTime, endTime;
13     unsigned array[ARRAY_SIZE];
14     long count = 0;
15
16     for (unsigned i = 0; i < ARRAY_SIZE; i++)
17         array[i] = rand();
18
19     startTime = clock();                                        // 分别使用 C++ 和 ASM 计算同一个函数
20     for (unsigned loop = 0; loop < LOOP_SIZE; loop++)
21         count = index(searchVal, array, ARRAY_SIZE);
22     endTime = clock();
23     cout << "Elapsed time: " << endTime - startTime << " ms, " << ((count == -1) ? "not" : "") << "found" << endl;
24
25     startTime = clock();
26     for (unsigned loop = 0; loop < LOOP_SIZE; loop++)
27         count = index2(searchVal, array, ARRAY_SIZE);
28     endTime = clock();
29     cout << "Elapsed time: " << endTime - startTime << " ms, " << ((count == -1) ? "not" : "") << "found" << endl;
30
31     getchar();
32     return 0;
33 }

原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9696495.html

时间: 2024-10-10 06:44:53

《汇编语言 基于x86处理器》第十三章高级语言接口部分的代码 part 1的相关文章

《汇编语言 基于x86处理器》第九章字符串与数组部分的代码

? 书中第九章的程序,主要讲了 ● 代码,Irvine32 中的字符串库函数代码范例 1 INCLUDE Irvine32.inc 2 3 .data 4 str1 BYTE "abcde////", 0 5 str2 BYTE "ABCDE", 0 6 msg0 BYTE "Upper case: ", 0 7 msg1 BYTE "str1 == str2", 0 8 msg2 BYTE "str1 < s

汇编语言:基于 X86 处理器第三章复习笔记

一:基本语言元素 1:整数常量 整数常量表达式:[{ + / - }] digits [ radix ] 整数常量的表达与进制是分不开的,通常通过在尾部添加字母加以区分: 十六进制 h 十进制   t(一般省略) 八进制   o/q 二进制   b 编码实数 r 注意:以字母开头的十六进制为了与标识符分区,必须在前面加数字 0 2:整形常量表达式 整形常量表达式是指一种算术表达式,由整数常量,算术运算符构成,注意:整形常量表达式的运算结果也必须是一个整数常量,其位数应该在处理器的位数之内 算术表

《汇编语言 基于x86处理器》第十一章 MS-DOS 编程部分的代码 part 2

? 书中第十一章的程序,主要讲了 Windows 接口,在小黑框中进行程序交互 ● 在屏幕指定位置输出带自定义属性的文字 1 INCLUDE Irvine32.inc 2 3 .data 4 outHandle HANDLE ? 5 cellsWritten DWORD ? ; 输出计数(输出参数) 6 xyPos COORD <10,2> ; 输出坐标 7 buffer BYTE 41h,42h,43h,44h,45h,46h,47h,48h,49h,4Ah,4Bh,4Ch,4Dh,4Eh,

《汇编语言 基于x86处理器》第十章结构和宏部分的代码

? 书中第十章的程序,主要讲了结构与宏的使用 ● 代码,使用结构,对比是否对齐的性能差距 1 INCLUDE Irvine32.inc 2 INCLUDE macros.inc 3 4 structN STRUCT ; 非对齐的结构 5 Lastname BYTE 30 DUP(0) ; 30 6 Years WORD 0 ; 2 7 SalaryHistory DWORD 0, 0, 0, 0 ; 16 8 structN ENDS ; 48 Byte 9 10 structA STRUCT

“全栈2019”Java第六十三章:接口与抽象方法详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第六十三章:接口与抽象方法详解 下一章 "全栈2019"Java第六十四章:接口与静态方法详解 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&qu

二十三章——相应路径下的代码统计

这里运用了流等知识写了一个小工具,可以统计某个路径下的代码的行数: package com.maya.hanqi.coder; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; public class CodeCounter { private static

Android研究之为基于 x86 的 Android* 游戏选择合适的引擎详解

摘要 游戏开发人员知道 Android 中蕴藏着巨大的机遇. 在 Google Play 商店的前 100 款应用中,约一半是游戏应用(在利润最高的前 100 款应用中,它们所占的比例超过 90%). 如要跻身该市场,开发速度非常关键. 一些刚起步的独立开发人员更愿意从零开始来开发自己的所有代码:但是为了达到更高的质量而不用花费数年的时间进行开发,其他人可能会选择已有的游戏引擎.上章研究了英特尔 Android* 开发人员指南上的对等应用详解,在选择引擎时,你可以考虑以下几个因素: 成本 - 你

第十三章、大规模数据库架构

第十三章.大规模数据库架构 内容提要: 1.了解分布式数据库技术 2.了解并行数据库技术 3.了解云数据库技术 4.了解XML数据库技术 第一节 分布式数据库 1.1.分布式数据库系统概述 分布式数据库系统与分布式数据库的区别: 分布式数据库系统--数据分布存储于若干场地,并且每个场地由独立于其它场地的DBMS进行数据管理.物理上分散.逻辑上集中的数据库系统. 分布式数据库--分布式数据库系统中各场地上数据库的逻辑集合. 1.2.分布式数据库目标与数据分布策略 分布式数据库目标: 12个目标:

JavaScript高级程序设计:第十三章

第十三章 一.理解事件流 事件流描述的是从页面中接收事件的顺序. 1.事件冒泡 IE的事件流叫做事件冒泡,即事件开始时由最具体的元素接收,然后逐级向上传播到较为不具体的节点.以下面的HTML页面为例: <!DOCTYPE html> <html> <head> <title>Event Bubling Example</title> </head> <body> <div id="myDiv"&g