《汇编语言 基于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                      ; 对齐的结构
11     Lastname BYTE 30 DUP(0)         ; 30
12     ALIGN    WORD                   ; +2
13     Years    WORD 0                 ;  2
14     ALIGN    DWORD                  ; +2 
15     SalaryHistory DWORD 0, 0, 0, 0  ; 16
16 structA ENDS                        ; 52 Byte
17 
18 .data
19 ALIGN DWORD                         ; 对齐到双字
20 startTime DWORD ?
21 empBad structN <>
22 emp structA <>
23 
24 .code
25 main PROC
26     call    GetMSeconds
27     mov     startTime, eax    
28     mov     ecx, 0FFFFFFFFh
29 L1:
30     mov     empBad.Years, 5
31     mov     empBad.SalaryHistory, 35000
32     loop    L1
33 
34     call    GetMSeconds       
35     sub     eax, startTime
36     mWrite  "Time without align: "
37     call    WriteDec          
38     call    Crlf
39 
40     call    GetMSeconds
41     mov     startTime, eax    
42     mov     ecx, 0FFFFFFFFh
43 L2:
44     mov     emp.Years, 5
45     mov     emp.SalaryHistory, 35000
46     loop    L2
47 
48     call    GetMSeconds        ; get starting time
49     sub     eax, startTime
50     mWrite  "Time with align: "
51     call    WriteDec            ; display elapsed time
52     call    Crlf
53     
54     call    WaitMsg
55     exit
56 main ENDP
57 
58 END main

■ 输出结果,反复测试,时间差大概在 70 ms 左右

Time without align: 6999
Time with align: 6913

● 调用 win32 API 显示时间,并放到终端中的指定位置

 1 INCLUDE Irvine32.inc
 2 
 3 COMMENT !
 4 SmallWin.inc 中关于结构 COORD 和 SYSTEMTIME 的定义
 5 COORD STRUCT    
 6   X     WORD ?
 7   Y     WORD ?
 8 COORD ENDS
 9 
10 SYSTEMTIME STRUCT
11     wYear           WORD ?
12     wMonth          WORD ?
13     wDayOfWeek      WORD ?
14     wDay            WORD ?
15     wHour           WORD ?
16     wMinute         WORD ?
17     wSecond         WORD ?
18     wMilliseconds   WORD ?
19 SYSTEMTIME ENDS
20 !
21 
22 .data
23 sysTime SYSTEMTIME <>
24 XYPos   COORD <10, 5>
25 consoleHandle DWORD ?
26 colonStr BYTE ":", 0
27 TheTimeIs BYTE "The time is ", 0
28 
29 .code
30 main PROC
31     INVOKE  GetStdHandle, STD_OUTPUT_HANDLE  ; 获取标准输出句柄,返回值在 eax,转入变量 consoleHandle
32     mov     consoleHandle, eax
33 
34     INVOKE  SetConsoleCursorPosition,  consoleHandle,  XYPos ; 设置终端光标位置
35     
36     INVOKE  GetLocalTime, ADDR sysTime                       ; 获取当前时间
37 
38     movzx   eax, sysTime.wHour          ; 小时
39     call    WriteDec
40     mov     edx, offset colonStr        ; ":"
41     call    WriteString
42     movzx   eax, sysTime.wMinute        ; 分钟
43     call    WriteDec
44     call    WriteString                 ; ":"
45     movzx   eax, sysTime.wSecond        ;
46     call    WriteDec
47     
48     call    Crlf
49     call    WaitMsg
50     exit
51 main ENDP
52 
53 END main

● 使用宏包装以后的汇编 Wraps.asm,主要展示了 Macros.inc 的作用

 1 INCLUDE Irvine32.inc
 2 INCLUDE Macros.inc
 3 
 4 .data
 5 array DWORD 1, 2, 3, 4, 5, 6, 7, 8
 6 string1 BYTE 31 DUP(?)
 7 string2  BYTE 31 DUP(?)
 8 
 9 .code
10 main PROC
11     mGotoxy 0, 0                                        ; 调整终端光标位置,并输出指定字符串
12     mWrite <"Macro Program sample:", 0dh, 0ah>
13 
14     mGotoxy 0, 5
15     mWrite <"Go to Row 5, col 0.", 0dh, 0ah>
16     call Crlf
17 
18     mWrite "Input string 1: "                           ; 输入两个字符串,然后一并输出
19     mReadString string1
20     call Crlf
21 
22     mWrite "Input string 2:"
23     mReadString string2
24     call Crlf
25 
26     mWrite "Output the strings:"
27     mWriteString string1
28     mWriteSpace
29     mWriteString string2
30     call Crlf
31 
32     mDumpMem OFFSET array, LENGTHOF array,  TYPE array  ; 输出数组
33 
34     call waitmsg
35     exit
36 main ENDP
37 
38 END main

 ● 代码,使用 WHILE 伪指令在编译阶段进行计算

 1 INCLUDE Irvine32.inc
 2 
 3 .data
 4 val1  = 1               ; 先给三个常量,然后再定义成变量
 5 val2  = 1
 6 val3 = val1 + val2
 7 DWORD val1
 8 DWORD val2
 9 DWORD val3
10 
11 WHILE val3 LT 00010000h ; 使用 WHILE 在编辑阶段进行展开和计算
12     val1 = val2
13     val2 = val3
14     val3 = val1 + val2
15 ENDM
16 
17 .code
18 main PROC
19     mov     eax, val3   ; 结果放进 eax 用于输出
20     call    WriteDec
21     call    crlf
22     call    WaitMsg
23     exit
24 main ENDP
25 
26 END main

● 代码,使用 REPEAT 生成单链表

 1 INCLUDE Irvine32.inc
 2 
 3 ListNode STRUCT                                 ; 链表节点结构
 4   NodeData DWORD ?
 5   NextPtr  DWORD ?
 6 ListNode ENDS
 7 
 8 TotalNodeCount = 15
 9 NULL = 0
10 Counter = 0
11 
12 .data
13 LinkedList LABEL PTR ListNode
14 REPT TotalNodeCount
15     Counter = Counter + 1
16     ListNode <Counter,  ($ + Counter * SIZEOF ListNode)>    ; 设置 next 指针要计算偏移量
17     ;ListNode <Counter,  ($ + SIZEOF ListNode)>             ; 没有偏移量,next 指针指向自身,错误
18 ENDM
19 ListNode <0, 0>                                 ; 尾节点
20 
21 .code
22 main PROC
23     mov     esi, OFFSET LinkedList
24 
25 NextNode:                                       ; 打印链表
26     mov     eax, (ListNode PTR [esi]).NextPtr   ; 检测是否是尾节点
27     cmp     eax, NULL                           ; next 指针为空,说明已经到尾部了
28     je      quit
29 
30     mov     eax, (ListNode PTR [esi]).NodeData  ; 打印节点保存的值
31     call    WriteDec
32     call    Crlf
33 
34     mov     esi, (ListNode PTR [esi]).NextPtr   ; 移向下一节点
35     jmp     NextNode
36 
37 quit:
38     call    WaitMsg
39     exit
40 main ENDP
41 
42 END main
原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9648863.html