zoukankan      html  css  js  c++  java
  • Intel汇编语言程序设计学习-第六章 条件处理-下

    6.6  应用:有限状态机

        这个东西说了半天,感觉就是把逻辑弄得跟有向图一样,没看出来什么高端的东西,下面就整理下书上说的概念:

    有限状态机(FSMFinite-State Machine)是依据输入改变状态机器或程序。使用图来表示一个有限状态机是非常简单的,图种方块(或原)称为节点,节点之间带箭头的线称为边(edge)或弧(arc)。

     

    6.6.1  输入字符串的验证

        读取输入流程的程序通常必须执行一定的错误检查步骤以验证输入。比如我们定义如下几条规则:

    1.字符串必须以字母x开始,以字母z结束。

    2.在第一个和最后一个字符之间,可以有0或多个字符,但字符必须在范围{‘a’~’y’}之内。

     

    6.6.2  有符号整数的验证

     

        有限状态机很容易翻译成汇编代码。图中的每个状态(A,B,C...)都由程序中一个标号标识,各标号处执行以下动作:

        A:调用输入过程,从输入中读取下一个字符。

        B:如果是终结状态,则检查用户是否输入了回车结束输入。

        C:使用一条或多条比较指令检查从当前状态到其他状态的可能转换,每条比较指令后面都紧跟一条跳转指令。

        实现下上面的那和输入检测:

    TITLE Finite State Machine  (Finite.asm)

    INCLUDE Irvine32.inc

    ENTER_KEY = 13

    .data

    InvalidinputMsg BYTE "Invalid input" ,13 ,10 ,0

    .code

    main PROC

        call Clrscr

    StateA:

        call Getnext

    cmp  al ,'+'

    je   StateB

    cmp  al ,'-'

    je   StateB

    call IsDigit

    jz   StateC

    call DisplayErrorMsg

    jmp  Quit

    StateB:

        call Getnext

    call IsDigit

    jz   StateC

    call DisplayErrorMsg

    jmp  Quit

    StateC:

        call Getnext

    call IsDigit

    jz   StateC

    cmp  al ,ENTER_KEY

    je   Quit

    call DisplayErrorMsg

    jmp  Quit

    Quit:

        call  Crlf

    exit

    main ENDP

     

    ;--------------------------------

    Getnext PROC

    ;

    ;Read a character from standard input.

    ;Receives : nothing

    ;Returns  : nothing

    ;--------------------------------

        call ReadChar

    call WriteChar

    ret

    Getnext ENDP

     

    ;--------------------------------

    DisPlayErrorMsg PROC

    ;Display an error message indicating that

    ;the input stream contains illegal input.

    ;Receives : nothing

    ;Returns  : nothing

    ;--------------------------------

        push  edx

    mov   edx ,OFFSET InvalidInputMsg

    call  WriteString

    pop   edx

    ret

    DisPlayErrorMsg  ENDP

    END main

     

    对应的流程图:

     

    6.7  决策伪指令

        MASM的决策伪指令{.IF .ELSE .ELSEIF .ENDIF}使得在编写涉及到多路分支逻辑的代码时更加容易。汇编器在幕后为这些伪指令自动生成CMP和条件跳转指令。

    .IF condition1

        statements

    [.ELSEIF condition2

        statements ]

    [.ELSE

        statements ]

    .ENDIF

        方括号是是可选部分,但是.IF.ENDIF是必须的。可支持的关系运算符如下:


    6.7.1  有符号比较和无符号比较

        这一节想表达的意思是.IF...比较有符号和无符号的时候,汇编器最后翻译的代码是不一样的。这个很好理解 比如 JA JB 对应的是 JG JL等等。

    6.7.2  复合表达式

        这一节是说.IF等可以直接使用 && || ..等逻辑算数符,和高级语言一样。

    6.7.3  .REPEAT.WHILE伪指令

    .WHILE C++等语言里的while差不多,格式是这样

    .WHILE  condition

    statements

    .ENDW

    .REPEAT则类似 DO...WHILE格式是这样:

    .REPEAT

        statements

    .UNTILE condition


        写个小例子,计算数组中大于等于4小于6的所有数之和:

    刚开始写这个简答的小程序的时候有个小插曲,

    .IF [esi] >= 4 的地方编译不过去,然后 .IF DWORD PTR[esi]可以编译过去,但是add eax ,[esi]却可以,woc我突然忘记怎么遍历数组了。于是就又查了之前的笔记,下面我用三种方式实现(为了练习):

    1.

    TITLE Finite State Machine  (Finite.asm)

    INCLUDE Irvine32.inc

    ENTER_KEY = 13

    .data

    intArray DWORD 1,2,3,4,5,6,7,8,9,10

    .code

    main PROC

        mov esi ,OFFSET intArray

    mov edx ,0

    mov eax ,0

    .WHILE edx < 10

        .IF DWORD PTR [esi] >=4 && DWORD PTR[esi] < 6

            add eax ,DWORD PTR [esi]

    .ENDIF

    add edx ,1

    add esi ,TYPE DWORD

       .ENDW

       call WriteInt

    exit

    main ENDP

    END main

     

    2.

    TITLE Finite State Machine  (Finite.asm)

    INCLUDE Irvine32.inc

    ENTER_KEY = 13

    .data

    intArray DWORD 1,2,3,4,5,6,7,8,9,10

    .code

    main PROC

        mov esi ,OFFSET intArray

    mov edx ,0

    mov eax ,0

    .WHILE edx < 10

        .IF  DWORD PTR[esi] >=4 && DWORD PTR[esi] < 6

            add eax ,[esi]

    .ENDIF

    add edx ,1

    add esi ,TYPE DWORD

       .ENDW

       call WriteInt

    exit

    main ENDP

    END main

    3.

    TITLE Finite State Machine  (Finite.asm)

    INCLUDE Irvine32.inc

    ENTER_KEY = 13

    .data

    intArray DWORD 1,2,3,4,5,6,7,8,9,10

    .code

    main PROC

        mov esi ,0

    mov edx ,0

    mov eax ,0

    .WHILE edx < 10

        .IF  intArray[esi] >=4 && intArray[esi] < 6

            add eax ,intArray[esi]

       .ENDIF

       add edx ,1

       add esi ,TYPE DWORD

       .ENDW

       call WriteInt

    exit

    main ENDP

    END main

     

     

     

     

    运行结果:(第三种)

     

    6.8本章小结

        我没有必要去总结书上的总结,还是直接粘贴过来:


     


     

     

     

     

     

  • 相关阅读:
    关于编码的问题(转)
    XML巩固
    浏览器兼容问题的解决方案
    JavaScript 全局变量命名空间生成函数
    表格的使用(转)
    post上传文件
    安装cocoapods
    UILabel内容模糊
    动态获取键盘高度
    iOS多线程同步锁
  • 原文地址:https://www.cnblogs.com/csnd/p/12062273.html
Copyright © 2011-2022 走看看