Intel汇编语言程序设计学习-第六章 条件处理-下
6.6 ?應用:有限狀態機
? ? 這個東西說了半天,感覺就是把邏輯弄得跟有向圖一樣,沒看出來什么高端的東西,下面就整理下書上說的概念:
有限狀態機(FSM,Finite-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本章小結
? ? 我沒有必要去總結書上的總結,還是直接粘貼過來:
 
?
 
?
?
?
?
?
總結
以上是生活随笔為你收集整理的Intel汇编语言程序设计学习-第六章 条件处理-下的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Intel汇编语言程序设计学习-第六章
- 下一篇: Windows核心编程 第四章 进程(中
