• 《汇编语言 基于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
  • 相关阅读:
    JQuery实现Ajax应用
    访问本地json文件因跨域导致的问题
    python_控制台输出带颜色的文字方法
    查询数据量大时,你会选择关联表查询还是循环中依个查询? up
    自己动手写SQL字符串分解函数Split up
    关于Access数据库执行Update语句后,不报错,但影响行数总是返回0的问题...... up
    TCP和UDP的区别
    Linxu系统下怎么安装vim编辑器
    网络编程 委托
    学习POS的数据包分析
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9648863.html
Copyright © 2020-2023  润新知