• 《汇编语言 基于x86处理器》第六章条件处理部分的代码


    ▶ 书中第六章的程序,使用了条件判断和跳转来实现一些功能

    ● 代码,查找数组首个非零值

     1 INCLUDE Irvine32.inc
     2 
     3 .data
     4 intArray SWORD  0, 0, 0, 0, 1, 20, 35, -12, 66, 4, 0   ; 测试用的数组
     5 ;intArray SWORD  1, 0, 0, 0
     6 ;intArray SWORD  0, 0, 0, 0
     7 ;intArray SWORD  0, 0, 0, 1
     8 noneMsg  BYTE "Non-zero value not found", 0
     9 
    10 .code
    11 main PROC
    12     mov   ebx, OFFSET intArray
    13     mov   ecx, LENGTHOF intArray
    14 
    15 L1:
    16     cmp   WORD PTR [ebx], 0     ; 与 0 作比较
    17     jnz   found                 ; 结果非零即找到了                 
    18     add   ebx, TYPE intArray
    19     loop  L1
    20     jmp   notFound
    21 
    22 found:
    23     movsx eax, WORD PTR [ebx]
    24     call  WriteInt
    25     jmp   quit
    26 
    27 notFound:
    28     mov   edx, OFFSET noneMsg
    29     call  WriteString
    30 
    31 quit:
    32     call  crlf
    33     call WaitMsg
    34 main ENDP
    35 
    36 END main

    ● 代码,简单的加密 / 解密

     1 INCLUDE Irvine32.inc
     2 KEY     = 239                       ; 用来异或的秘钥
     3 BUFMAX  = 128
     4 
     5 .data
     6 sPrompt  BYTE   "Plain text:    ", 0
     7 sEncrypt BYTE   "Cipher text:   ", 0
     8 sDecrypt BYTE   "Decrypted:     ", 0
     9 buffer   BYTE   BUFMAX + 1      DUP(0)
    10 bufSize  DWORD  ?
    11 
    12 .code
    13 main PROC
    14     call    InputTheString          ; 输入
    15 
    16     call    TranslateBuffer         ; 加密并输出
    17     mov     edx,    OFFSET sEncrypt
    18     call    DisplayMessage
    19 
    20     call    TranslateBuffer         ; 解密并输出
    21     mov     edx,    OFFSET sDecrypt
    22     call    DisplayMessage
    23 
    24     call    WaitMsg
    25     exit
    26 main ENDP
    27 
    28 InputTheString PROC
    29     pushad                          ; 寄存器全压栈
    30     mov     edx,    OFFSET sPrompt
    31     call    WriteString
    32     mov     ecx,    BUFMAX
    33     mov     edx,    OFFSET buffer
    34     call    ReadString
    35     mov     bufSize,eax
    36     call    Crlf
    37     popad                           ; 寄存器全恢复,返回值在 buffer 里
    38     ret
    39 InputTheString ENDP
    40 
    41 DisplayMessage PROC
    42     pushad
    43     call    WriteString
    44     mov     edx,    OFFSET buffer
    45     call    WriteString
    46     call    Crlf
    47     call    Crlf
    48     popad
    49     ret
    50 DisplayMessage ENDP
    51 
    52 TranslateBuffer PROC
    53     pushad
    54     mov     ecx, bufSize
    55     mov     esi, 0
    56 L1:
    57     xor     buffer[esi], KEY    ; 用一个循环来逐字节异或
    58     inc     esi
    59     loop    L1
    60 
    61     popad
    62     ret
    63 TranslateBuffer ENDP
    64 END main

    ● 代码,表驱动选择

     1 INCLUDE Irvine32.inc
     2 .data
     3 CaseTable  BYTE   'A'           ; 驱动表,交替存储选项和分支
     4            DWORD   Process_A    
     5            BYTE   'B'
     6            DWORD   Process_B
     7            BYTE   'C'
     8            DWORD   Process_C
     9            BYTE   'D'
    10            DWORD   Process_D
    11 NumberOfEntries = 4
    12 
    13 prompt BYTE "Input A, B, C or D: ", 0
    14 msgA BYTE "Process_A", 0
    15 msgB BYTE "Process_B", 0
    16 msgC BYTE "Process_C", 0
    17 msgD BYTE "Process_D", 0
    18 
    19 .code
    20 main PROC
    21     mov  edx, OFFSET prompt     ; 输入字符
    22     call WriteString
    23     call ReadChar
    24     mov  ebx, OFFSET CaseTable  ; ebx 指向表
    25     mov  ecx, NumberOfEntries
    26 L1:
    27     cmp  al, [ebx]              ; 是否匹配 ebx 指向的项
    28     jne  L2                     ; 否分支
    29     call NEAR PTR [ebx + 1]     ; 是分支,调用对应的子过程(过程指针解引用,NEAR PTR)
    30     call WriteString            ; 显示相应的信息并退出循环
    31     call Crlf
    32     jmp  L3
    33 
    34 L2:
    35     add  ebx, 5                 ; 指向表中下一项
    36     loop L1
    37 
    38 L3:
    39     exit
    40 
    41     call WaitMsg
    42 main ENDP
    43 
    44 Process_A PROC
    45     mov  edx, OFFSET msgA
    46     ret
    47 Process_A ENDP
    48 
    49 Process_B PROC
    50     mov  edx, OFFSET msgB
    51     ret
    52 Process_B ENDP
    53 
    54 Process_C PROC
    55     mov  edx, OFFSET msgC
    56     ret
    57 Process_C ENDP
    58 
    59 Process_D PROC
    60     mov  edx, OFFSET msgD
    61     ret
    62 Process_D ENDP
    63 
    64 END main

    ● 代码,简单反汇编输出

     1 INCLUDE Irvine32.inc
     2 
     3 .data
     4 TRUE = 1
     5 FALSE = 0
     6 gradeAverage  WORD 275
     7 credits       WORD 12
     8 OkToRegister  BYTE ?
     9 
    10 .code
    11 main PROC
    12     mov OkToRegister,FALSE
    13 
    14     .IF gradeAverage > 350
    15        mov OkToRegister,TRUE
    16     .ELSEIF (gradeAverage > 250) && (credits <= 16)
    17        mov OkToRegister,TRUE
    18     .ELSEIF (credits <= 12)
    19        mov OkToRegister,TRUE
    20     .ENDIF
    21 
    22     exit
    23 main ENDP
    24 
    25 END main

    ■ 反汇编后,

     1 _main@0:
     2 002E1005  jmp         main (02E1010h)
     3 002E100A  int         3
     4 002E100B  int         3
     5 002E100C  int         3
     6 002E100D  int         3
     7 002E100E  int         3
     8 002E100F  int         3
     9 --- D:Codeassemblerproject6asm6asm6haha.asm ------------------------------
    10 
    11     mov OkToRegister,FALSE
    12 002E1010  mov         byte ptr [OkToRegister (02E4004h)],0
    13 
    14     .IF gradeAverage > 350
    15 002E1017  cmp         word ptr [gradeAverage (02E4000h)],15Eh
    16 002E1020  jbe         @C0001 (02E102Bh)
    17        mov OkToRegister,TRUE
    18 002E1022  mov         byte ptr [OkToRegister (02E4004h)],1
    19     .ELSEIF (gradeAverage > 250) && (credits <= 16)
    20 002E1029  jmp         @C0001+2Fh (02E105Ah)
    21 @C0001:
    22 002E102B  cmp         word ptr [gradeAverage (02E4000h)],0FAh
    23 002E1034  jbe         @C0001+1Eh (02E1049h)
    24 002E1036  cmp         word ptr [credits (02E4002h)],10h
    25 002E103E  ja          @C0001+1Eh (02E1049h)
    26        mov OkToRegister,TRUE
    27 002E1040  mov         byte ptr [OkToRegister (02E4004h)],1
    28     .ELSEIF (credits <= 12)
    29 002E1047  jmp         @C0001+2Fh (02E105Ah)
    30 @C0004:
    31 002E1049  cmp         word ptr [credits (02E4002h)],0Ch
    32 002E1051  ja          @C0001+2Fh (02E105Ah)
    33        mov OkToRegister,TRUE
    34 002E1053  mov         byte ptr [OkToRegister (02E4004h)],1
    35     .ENDIF
    36 
    37     exit
    38 002E105A  push        0
    39 002E105C  call        _ExitProcess@4 (02E1075h)

    ● 代码,有限自动机判断输入的是否是一个合法的数字。注意每输入一个字符就进行状态跳转,而不是输入一行后回车才开始分析

     1 INCLUDE Irvine32.inc
     2 
     3 ENTER_KEY = 13              ; 回车键作为停止输入的标志
     4 .data
     5 InvalidInputMsg BYTE "Invalid input", 13, 10, 0
     6 
     7 .code
     8 main PROC
     9     call    Clrscr
    10 
    11 StateA:
    12     call    Getnext         ; 读取下一个字符
    13     cmp     al,'+'          ; 前导 +,前往状态 B
    14     je      StateB
    15     cmp     al,'-'          ; 前导 -,前往状态 B
    16     je      StateB
    17     call    IsDigit         ; 数字,置 ZF = 1,前往状态 C
    18     jz      StateC
    19     call    DisplayErrorMsg ; 错误状态
    20     jmp     Quit
    21 
    22 StateB:
    23     call    Getnext
    24     call    IsDigit
    25     jz      StateC
    26     call    DisplayErrorMsg
    27     jmp    Quit
    28 
    29 StateC:
    30     call    Getnext
    31     call    IsDigit
    32     jz      StateC
    33     cmp     al, ENTER_KEY
    34     je      Quit
    35     call    DisplayErrorMsg
    36     jmp     Quit
    37 
    38 Quit:
    39     call    Crlf
    40     call    WaitMsg
    41     exit
    42 main ENDP
    43 
    44 Getnext PROC
    45      call ReadChar
    46      call WriteChar
    47      ret
    48 Getnext ENDP
    49 
    50 DisplayErrorMsg PROC
    51      push   edx
    52      mov    edx, OFFSET InvalidInputMsg
    53      call   WriteString
    54      pop    edx
    55      ret
    56 DisplayErrorMsg ENDP
    57 END main
  • 相关阅读:
    js中当call或者apply传入的第一个参数是null/undefined时,js函数内执行的上下文环境是什么?
    闭包的实现原理和作用以及堆栈溢出和内存泄漏原理和相应解决办法
    JavaScript的作用域和作用域链
    词法作用域和动态作用域
    理解 es6 中class构造以及继承的底层实现原理
    new一个对象的详细过程,手动实现一个 new操作符
    实现继承的几种方式以及他们的优缺点
    理解JavaScript的执行上下文栈,可以应用堆栈信息快速定位问题
    原型和原型链-instanceof的底层实现原理
    js判断变量未定义
  • 原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9596397.html
Copyright © 2020-2023  润新知