匯編開發(fā)(四):條件處理

1. 條件分支

允許決策的編程語言允許您使用稱為條件分支的技術(shù)來改變控制流镶柱。在高級語言中姑曙,每個if狀態(tài),switch狀態(tài)纬向,分支循環(huán)都已經(jīng)有分支邏輯择浊,在匯編語言中,提供所有的你認為需要做的邏輯跳轉(zhuǎn)逾条。

2. Boolean 和Comparison 指令

Selected Boolean Instructions.png
1). CPU 狀態(tài)標識

Boolean 指令影響ZF琢岩,CF,SF师脂,OF担孔,PF標志位。

  • ZF:操作的結(jié)果為0時設(shè)置
  • CF:操作使目的操作數(shù)高位產(chǎn)生進位時設(shè)置吃警。
  • SF:如果復(fù)制目的操作數(shù)的高位時糕篇,設(shè)置為負;否則清除設(shè)置為正酌心。
  • OF:指令生成目的操作數(shù)在范圍之外的結(jié)果時設(shè)置拌消。
  • PF:指令生成目的操作的1的個數(shù)為奇數(shù)時設(shè)置。
2). AND 指令
  • 格式
AND destination, source

AND reg,reg
AND reg,mem
AND reg,imm
AND mem,reg
AND mem,imm

操作可以是8位安券,16位墩崩,32位或64位氓英,但他們必須是相同的大小。

AND.png

示例:

mov al,10101110b
and al,11110110b ; result in AL = 10100110

標志位:AND 指令總是清除OF鹦筹、CF铝阐。 目的操作數(shù)分配數(shù)值修改SF,ZF铐拐,PF徘键。

  • 轉(zhuǎn)換字符為大寫

AND 指令提供一個簡單的方式將小寫轉(zhuǎn)換為大寫,通過比較ASCII碼的方式進行轉(zhuǎn)換余舶,因為他們只有第5位是不同的啊鸭。

0 1 1 0 0 0 0 1 = 61h ('a')
0 1 0 0 0 0 0 1 = 41h ('A')
3). OR 指令
  • 格式
OR destination,source

OR reg,reg
OR reg,mem
OR reg,imm
OR mem,reg
OR mem,imm

操作可以是8位,16位匿值,32位或64位赠制,但他們必須是相同的大小。

OR.png

示例:

mov al,11100011b
or al,00000100b ; result in AL = 11100111

標記:AND 指令總是清除OF挟憔、CF钟些。 目的操作數(shù)分配數(shù)值修改SF,ZF绊谭,PF政恍。

ZF_PF.png
4). XOR 指令
  • 格式
XOR destination,source
XOR.png

標志位:AND 指令總是清除OF、CF达传。 目的操作數(shù)分配數(shù)值修改SF篙耗,ZF,PF宪赶。

5). NOR 指令
  • 格式
NOT reg
NOT mem

示例:

mov al,11110000b
not al              ; AL = 00001111b

標志位:沒有標志位被設(shè)置宗弯。

6). TEST 指令
  • 作用

TEST指令在兩個操作數(shù)中的每對匹配位之間執(zhí)行隱含的AND操作,并根據(jù)分配給目標操作數(shù)的值設(shè)置SF搂妻,ZF和PF標志蒙保。 與AND指令的區(qū)別僅在TEST指令不修改目標操作數(shù)。

test al,00001001b; test bits 0 and 3

標志位:AND 指令總是清除OF欲主、CF邓厕。 目的操作數(shù)分配數(shù)值修改SF,ZF扁瓢,PF详恼。

7). CMP 指令
  • 作用
    比較兩個整數(shù)的大小

  • 格式

CMP destination,source

標志位:CMP指令根據(jù)目標操作數(shù)在發(fā)生實際減法時所具有的值來更改溢出,符號引几,零单雾,進位,輔助進位和奇偶校驗標志。

ZF_CF.png

示例:

mov ax,5
cmp ax,10           ; ZF = 0 and CF = 1

mov ax,1000
mov cx,1000
cmp cx,ax           ; ZF = 1 and CF = 0

mov si,105
cmp si,0            ; ZF = 0 and CF = 0
8). 設(shè)置和清除標志位
  • 設(shè)置零標記位
test al,0       ; set Zero flag
and al,0        ; set Zero flag
or al,1         ; clear Zero flag
  • 設(shè)置符號標記位
or al,80h       ; set Sign flag
and al,7Fh      ; clear Sign flag
  • 設(shè)置進位標志位
stc         ; set Carry flag
clc         ; clear Carry flag
  • 設(shè)置溢出標記位
mov al,7Fh      ; AL = +127
inc al          ; AL = 80h (-128), OF=1
or eax,0        ; clear Overflow flag

3. 分支跳轉(zhuǎn)

1). 分支結(jié)構(gòu)
  • 示例1
    cmp eax,0
    jz L1       ; jump if ZF = 1
    .
    .
L1:
  • 示例2
    and dl,10110000b
    jnz L2 ;            jump if ZF = 0
    .
    .
L2:
2). Jcond 指令
  • 作用
    當狀態(tài)標志條件為真時硅堆,條件跳轉(zhuǎn)指令分支到目標標簽屿储。

  • 格式

Jcond destination

其中cond指的是標識一個或多個標志的狀態(tài)的標志條件。例如基與CF與ZF標志位跳轉(zhuǎn)如下:

Jcond.png
  • 使用CMP 指令
cmp eax,5
je L1       ; 當EAX值等于5的時候跳轉(zhuǎn)到L1

mov ax,5
cmp ax,6
jl L1       ; 當AX值小于6的時候跳轉(zhuǎn)到L1

mov ax,5
cmp ax,4
jg L1       ; 當AX值大于4的時候跳轉(zhuǎn)到L1
3). 條件跳轉(zhuǎn)指令類型
  • 跳轉(zhuǎn)指令集的四種分組

    • 基于特殊寄存器
    • (E)CX 操作數(shù)之間是否相等
    • 無符號操作數(shù)比較
    • 有符號操作數(shù)比較

下表位基于ZF渐逃,CF够掠,OF,PF茄菊,SF標志位的跳轉(zhuǎn)指令

Jumps Based on Specific Flag Values.png
  • 等于比較

在一些情況下兩個操作數(shù)進行比較疯潭;另一些情況下,基于CX/ECX/RCX比較面殖。

CMP leftOp,rightOp

下面是基于等號的跳轉(zhuǎn)指令

Jumps Based on Equality.png
  • 示例: JE, JNE, JCXZ, and JECXZ
Example 1:
    mov edx,0A523h
    cmp edx,0A523h
    jne L5              ; jump not taken
    je L1               ; jump is taken

Example 2:
    mov bx,1234h
    sub bx,1234h
    jne L5              ; jump not taken
    je L1               ; jump is taken

Example 3:
    mov cx,0FFFFh
    inc cx
    jcxz L2             ; jump is taken

Example 4:
    xor ecx,ecx
    jecxz L2            ; jump is taken
  • 無符號比較
Jumps Based on Unsigned Comparisons.png
  • 有符號比較
Jumps Based on Signed Comparisons.png

示例:

Example 1
    mov edx,-1
    cmp edx,0
    jnl L5          ; jump not taken (-1 >= 0 is false)
    jnle L5         ; jump not taken (-1 > 0 is false)
    jl L1           ; jump is taken (-1 < 0 is true)

Example 2
    mov bx,+32
    cmp bx,-35
    jng L5          ; jump not taken (+32 <= -35 is false)
    jnge L5         ; jump not taken (+32 < -35 is false)
    jge L1          ; jump is taken (+32 >= -35 is true)

Example 3
    mov ecx,0
    cmp ecx,0
    jg L5           ; jump not taken (0 > 0 is false)
    jnl L1          ; jump is taken (0 >= 0 is true)

Example 4
    mov ecx,0
    cmp ecx,0
    jl L5           ; jump not taken (0 < 0 is false)
    jng L1          ; jump is taken (0 <= 0 is true)
4). 條件跳轉(zhuǎn)應(yīng)用
  • 測試狀態(tài)位
mov al,status
test al,00100000b ; test bit 5
jnz DeviceOffline
  • 兩個數(shù)比較大小
    mov edx,eax ; assume EAX is larger
    cmp eax,ebx ; if EAX is >= EBX
    jae L1      ; jump to L1
    mov edx,ebx ; else move EBX to EDX
L1:             ; EDX contains the larger integer
  • 三個數(shù)中求最小
.data
    V1 WORD ?
    V2 WORD ?
    V3 WORD ?
.code
    mov ax,V1   ; assume V1 is smallest
    cmp ax,V2   ; if AX <= V2
    jbe L1      ; jump to L1
    mov ax,V2   ; else move V2 to AX
L1: 
    cmp ax,V3   ; if AX <= V3
    jbe L2      ; jump to L2
    mov ax,V3   ; else move V3 to AX
L2:
  • 循環(huán)直到有鍵按下
.data
    char BYTE ? 
.code
L1: 
    mov eax,10      ; create 10 ms delay
    call Delay
    call ReadKey    ; check for key
    jz L1           ; repeat if no key
    mov char,AL     ; save the character
5). 應(yīng)用: 順序搜索數(shù)組
; 掃描數(shù)組
; 掃描數(shù)組中的非0值

INCLUDE Irvine32.inc

.data
    intArray SWORD 0, 0, 0, 0, 1, 20, 35, -12, 66, 4, 0     ; 無符號整型數(shù)組
    noneMsg BYTE "A non-zero value was not found", 0        ; 提示信息

.code

main PROC
    mov ebx, OFFSET intArray        ; 數(shù)組指針
    mov ecx, LENGTHOF intArray      ; 循環(huán)計數(shù)

L1:
    cmp WORD PTR [ebx], 0           ; 與0比較
    jnz found                       ; 發(fā)現(xiàn)不等于0的值
    add ebx, 2                      ; 指向下一個數(shù)組元素
    LOOP L1                         ; 繼續(xù)循環(huán)
    jmp notFound                    ; 未發(fā)現(xiàn)

found:                              ; 顯示值
    movsx eax, WORD PTR [ebx]       ; 將有符號的值設(shè)置到EAX
    call WriteInt                   ; 輸出
    jmp quit                        ; 退出程序

notFound:                           ; 顯示未發(fā)現(xiàn)信息
    mov edx, OFFSET noneMsg
    call WriteString

quit:
    call Crlf
    exit
main ENDP

END
6). 應(yīng)用:簡單的字符串加密
  • 原理:( (X ? Y) ? Y) = X

  • 代碼:

; 加密文本
INCLUDE Irvine32.inc
KEY = 239                           ; 在1——255之間的任意數(shù)字
BUFMAX = 128                        ; 最大緩沖字節(jié)

.data
    sPrompt BYTE "Enter the plain text: ", 0    ; 輸入文本提示信息
    sEncrypt BYTE "Cipher text:  ", 0           ; 加密文本提示信息
    sDecrypt BYTE "Decryted:     ", 0           ; 解密文本提示信息
    buffer BYTE BUFMAX + 1 DUP(0)               ; 緩沖字節(jié)個數(shù)
    bufSize DWORD ?                             ; 緩沖字節(jié)

.code
main PROC
    call InputTheString             ; 輸入待加密文本
    call TranslateBuffer            ; 加密文本
    mov edx, OFFSET sEncrypt        ; 顯示加密信息
    call DisplayMessage             ; 調(diào)用顯示文本程序
    call TranslateBuffer            ; 解密緩沖文本
    mov edx, OFFSET sDecrypt        ; 顯示解密信息
    call DisplayMessage             ; 調(diào)用顯示文本程序

    call WaitMsg                    ; 顯示等待輸入任意鍵信息
    exit
main ENDP

;-------------------------------------------------------
; 提示用戶輸入一個待加密文本竖哩,保存字符串及長度
; Receives: 無
; Returns: 無
;-------------------------------------------------------
InputTheString PROC
    pushad                  ; 保存32位寄存器
    mov edx, OFFSET sPrompt ; 顯示提示信息
    call WriteString
    
    mov ecx, BUFMAX         ; 設(shè)置最大字符個數(shù)
    mov edx, OFFSET buffer  ; 設(shè)置緩沖指針
    call ReadString         ; 讀取字符串
    mov bufSize, eax        ; 存儲長度
    call Crlf

    popad
    RET
InputTheString ENDP

;-------------------------------------------------------
; 顯示信息
; Receives: EDX 指針消息
; Returns: 無
;-------------------------------------------------------
DisplayMessage PROC
    pushad
    call WriteString
    mov edx, OFFSET buffer      ; 顯示緩沖中的信息
    call WriteString
    call Crlf
    call Crlf
    popad
    RET
DisplayMessage ENDP

;-------------------------------------------------------
; 加解密文本
; Receives: 無
; Returns: 無
;-------------------------------------------------------
TranslateBuffer PROC
    pushad
    mov ecx, bufSize            ; 設(shè)置循環(huán)計數(shù)
    mov esi, 0                  ; 設(shè)置緩沖序號
L1:
    xor buffer[esi], KEY        ; 翻譯字節(jié)
    inc esi                     ; 指向下一個字節(jié)
    LOOP L1

    popad
    RET
TranslateBuffer ENDP

END
效果.png

4.循環(huán)條件指令

1). LOOPZ 和 LOOPE 指令
  • LOOPZ (Loop if zero)
    想LOOP一樣工作,附加條件:必須設(shè)置零標志脊僚,以便控制轉(zhuǎn)移到目標標簽相叁。 格式如下:
LOOPZ destination
  • LOOPE (Loop if equal)
    與LOOPZ用法相同。
2). LOOPNZ 和 LOOPNE 指令
  • LOOPNZ (Loop if not zero)
    與LOOPZ相反辽幌,循環(huán)繼續(xù)的條件是ECX無符號整數(shù)大于0并且ZF被清空增淹。格式如下:
LOOPNZ destination
  • LOOPNE (Loop if not equal)
    與LOOPE相反衔掸。

  • 示例

; 循環(huán)查找非負數(shù)
INCLUDE Irvine32.inc

.data
    array SWORD -3, -6, -1, -10, 10, 30, 40, 4
    sentinel SWORD 0

.code
main PROC
    mov esi, OFFSET array
    mov ecx, LENGTHOF array

L1:
    test WORD PTR [esi], 8000h      ; 設(shè)置符號位
    pushfd                          ; 將flags入棧
    add esi, TYPE array             ; 移動到下一個元素
    popfd                           ; 將flags出棧
    LOOPNZ L1   
    jnz  quit                       ; none found
    sub  esi,TYPE array             ; ESI points to value

quit:
    movsx eax,WORD PTR[esi]         ; display the value
    call WriteInt
    call crlf

    call WaitMsg                    ; 顯示等待輸入任意鍵信息
    exit
main ENDP

END

5. 條件結(jié)構(gòu)

1). IF 塊結(jié)構(gòu)
  • 示例1:

偽代碼:

if( boolean-expression )
    statement-list-1
else
    statement-list-2

匯編代碼:

    mov eax,op1
    cmp eax,op2     ; op1 == op2?
    jne L1          ; no: skip next
    mov X,1         ; yes: assign X and Y
    mov Y,2
L1:
  • 示例2:

偽代碼:

if op1 > op2
    call Routine1
else
    call Routine2
end if

匯編代碼:

    mov eax,op1     ; move op1 to a register
    cmp eax,op2     ; op1 > op2?
    jg A1           ; yes: call Routine1
    call Routine2   ; no: call Routine2
    jmp A2          ; exit the IF statement
A1: call Routine1
A2:
  • 示例3:

偽代碼:

if op1 == op2
    if X > Y
        call Routine1
    else
        call Routine2
    end if
else
    call Routine3
end if

匯編代碼:

    mov eax,op1
    cmp eax,op2     ; op1 == op2?
    jne L2          ; no: call Routine3
    ; process the inner IF-ELSE statement.
    mov eax,X
    cmp eax,Y       ; X > Y?
    jg L1           ; yes: call Routine1
    call Routine2   ; no: call Routine2
    jmp L3          ; and exit
L1: call Routine1   ; call Routine1
    jmp L3          ; and exit
L2: call Routine3
L3:
2). 符合表達式
  • 邏輯AND運算符

偽代碼:

if (al > bl) AND (bl > cl)
    X = 1
end if

匯編代碼:

    cmp al,bl ; first expression...
    ja L1
    jmp next
L1: 
    cmp bl,cl ; second expression...
    ja L2
    jmp next
L2: 
    mov X,1 ; both true: set X to 1
next:
3). WHILE 循環(huán)

偽代碼:

while( val1 < val2 )
{
    val1++;
    val2--;
}

匯編代碼:

    mov eax,val1 ; copy variable to EAX
beginwhile:
    cmp eax,val2 ; if not (val1 < val2)
    jnl endwhile ; exit the loop
    inc eax ; val1++;
    dec val2 ; val2--;
    jmp beginwhile ; repeat the loop
endwhile:
    mov val1,eax ; save new value for val1  

示例:循環(huán)中嵌套IF狀態(tài)

C++代碼:

int array[] = {10,60,20,33,72,89,45,65,72,18};
int sample = 50;
int ArraySize = sizeof array / sizeof sample;
int index = 0;
int sum = 0;
while( index < ArraySize )
{
    if( array[index] > sample )
    {
        sum += array[index];
    }
    index++;
}

匯編代碼:

; 判斷數(shù)組元素值是否大于50外驱, 如果大于則求和座哩。
INCLUDE Irvine32.inc

.data
    sum DWORD 0             ; 大于50的數(shù)組元素之和
    sample DWORD 50         ; 求和標準
    array DWORD 10, 60, 30, 33, 72, 89, 45, 65, 72, 18  ; 數(shù)組
    ArraySize = ($ - array) / TYPE array    ; 數(shù)組長度

.code
main PROC
    mov eax, 0              ; sum
    mov edx, sample
    mov esi, 0              ; 數(shù)組標識
    mov ecx, ArraySize

L1: 
    cmp esi, ecx            ; 判斷數(shù)組標識是否小于數(shù)組長度
    jl L2
    jmp L5                  ; 無條件跳轉(zhuǎn)

L2: 
    cmp array[esi * 4], edx ; 判斷數(shù)組元素的數(shù)值是否大于50
    jg L3
    jmp L4

L3: 
    add eax, array[esi * 4] ; 求和

L4: 
    inc esi                 ; 數(shù)組標識+1
    jmp L1                  ; 跳轉(zhuǎn)

L5:
    mov sum, eax            ; 設(shè)置和

    call WaitMsg            ; 顯示等待輸入任意鍵信息
    exit
main ENDP

END
4). 表驅(qū)動選擇

示例:用戶從鍵盤輸入朝蜘,根據(jù)輸入的字符查找對應(yīng)的字符串

; 用戶從鍵盤輸入,根據(jù)輸入的字符查找對應(yīng)的字符串
INCLUDE Irvine32.inc

.data
    CaseTable BYTE 'A'              ; 查找值
              DWORD Process_A       ; 程序的地址 
    EntrySize = ($ - CaseTable)
              BYTE 'B'
              DWORD Process_B       
              BYTE 'C'
              DWORD Process_C
              BYTE 'D'
              DWORD Process_D
    
    NumberOfEntries = ($ - CaseTable) / EntrySize
    prompt BYTE "Press capital A, B, C, or D: ", 0

    ; 定義每段程序的消息字符串
    msgA BYTE "Process_A", 0
    msgB BYTE "Process_B", 0
    msgC BYTE "Process_C", 0
    msgD BYTE "Process_D", 0

.code
main PROC
    mov edx, OFFSET prompt  ; 提示用戶輸入
    call WriteString
    call ReadChar           ; 從Al中讀取一個字符
    mov ebx, OFFSET CaseTable   ; EBX 指向表
    mov ecx, NumberOfEntries    ; 循環(huán)計數(shù)
L1:
    cmp al, [ebx]               ; 是否匹配
    jne L2                      ; 未發(fā)現(xiàn)因痛,繼續(xù)
    call NEAR PTR [ebx + 1]     ; 查找到燕耿,調(diào)用程序
    call WriteString            ; 顯示消息
    call Crlf               
    jmp L3
L2:
    add ebx, EntrySize          ; 指向下一個實體
    LOOP L1                     ; 重復(fù)低千,直到ECX = 0
L3: 
    call WaitMsg            ; 顯示等待輸入任意鍵信息
    exit
main ENDP

Process_A PROC
    mov edx, OFFSET msgA
    RET
Process_A ENDP

Process_B PROC
    mov edx, OFFSET msgB
    RET
Process_B ENDP

Process_C PROC
    mov edx, OFFSET msgC
    RET
Process_C ENDP

Process_D PROC
    mov edx, OFFSET msgD
    RET
Process_D ENDP

END

6. 有限狀態(tài)機

有限狀態(tài)機(FSM)是基于某些輸入改變狀態(tài)的機器或程序猪腕。

Simple finite-state machine.png
1). 驗證輸入字符串

程序在讀取輸入的字符串通常必須對輸入文本的異常檢測舞蔽。

2). 驗證有符號整型

程序驗證一個數(shù)字的符合正負號。

示例代碼:

; 有限狀態(tài)機
INCLUDE Irvine32.inc

ENTER_KEY = 13

.data
    InvalidInputMsg BYTE "Invalid input", 13, 10, 0

.code
main PROC
    call ClrScr

StateA:
    call Getnext        ; 讀取AL中的下一個字符
    cmp al, "+"         ; 判斷是否為+號
    je StateB           ; 等于就去StateB
    cmp al, "-"         ; 判斷是否為-號
    je StateB           ; 等于就去StateB
    call IsDigit        ; 判斷是否為數(shù)字, 如果AL包含數(shù)字码撰,則ZF等于1
    jz StateC           ; 等于就去StateC
    call DisplayErrorMsg; 顯示異常信息
    jmp Quit            ; 退出程序

StateB:
    call Getnext        ; 讀取AL中的下一個字符
    call IsDigit        ; 如果包含數(shù)字則ZF = 1
    jz StateC           ; ZF = 1則跳到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
    call WaitMsg
    exit
main ENDP

;------------------------------------------------
; 從標準輸入讀取一個字符
; Receives: 無
; Returns: AL 包含一個字符
;------------------------------------------------
Getnext PROC
    call ReadChar
    call WriteChar
    RET
Getnext ENDP

;------------------------------------------------
; 顯示錯誤信息
; Receives: 無
; Returns: 無
;------------------------------------------------
DisplayErrorMsg PROC USES edx
    call Crlf
    mov edx, OFFSET InvalidInputMsg
    call WriteString
    RET
DisplayErrorMsg ENDP

END

7. 條件控制流程指令

32位模式下,MASM包含一些高級的條件控制流程指令个盆,幫助我們簡單的使用條件狀態(tài)脖岛,但在64位模式下不可用。

Conditional Control Flow Directives.png
1). 創(chuàng)建IF狀態(tài)
  • 格式
.IF condition1
    statements
[.ELSEIF condition2
    statements ]
[.ELSE
    statements ]
.ENDIF
  • 條件可選表達式操作符
Runtime Relational and Logical Operators.png
  • 生成匯編代碼
mov eax,6
.IF eax > val1
    mov result,1
.ENDIF
2). 有符號和無符號比較
  • 無符號比較
.data
    val1 DWORD 5
    result DWORD ?
.code
    mov eax,6
    .IF eax > val1
        mov result,1
    .ENDIF
  • 有符號比較
.data
    val2 SDWORD -1
    result DWORD ?
.code
mov eax,6
    .IF eax > val2
        mov result,1
    .ENDIF
  • 寄存器比較
mov eax,6
mov ebx,val2
.IF eax > ebx
    mov result,1
.ENDIF
3). 符合表達式
  • 格式
.IF expression1 ||[&&] expression2
    statements
.ENDIF
  • 示例:設(shè)置光標位置
; 設(shè)置光標位置
INCLUDE Irvine32.inc

; 使用.IF 和 .ENDIF 指令設(shè)置光標的位置

.code
main PROC
    mov dl, 79      ; X軸
    mov dh, 24      ; Y軸
    call SetCursorPosition
    
    call Crlf
    call WaitMsg
    exit
main ENDP

;------------------------------------------------
; 設(shè)置光標位置
; Receives: DL: X軸颊亮, DH: Y軸
; Returns: 無
;------------------------------------------------
SetCursorPosition PROC
.data
    BadXCoordMsg BYTE "X-Coordinate out of range!", 0Dh, 0Ah, 0
    BadYCoordMsg BYTE "Y-Coordinate out of range!", 0Dh, 0Ah, 0
.code
    .IF (DL < 0) || (DL > 79)
        mov edx, OFFSET BadXCoordMsg
        call WriteString
        jmp quit
    .ENDIF
    .IF (DH < 0) || (DH > 24)
        mov edx, OFFSET BadYCoordMsg
        call WriteString
        jmp quit
    .ENDIF
    call Gotoxy             ; 修改x,y值

quit:
    RET
SetCursorPosition ENDP

END
  • 示例:大學注冊
; 大學生注冊
; 使用.IF, .ENDIF, .ELSEIF指令

INCLUDE Irvine32.inc

.data
    TRUE = 1
    FALSE = 0
    gradeAverage WORD 275   ; 測試值
    credits WORD 12         ; 測試值
    OkToRegister BYTE ?

.code
main PROC
    mov OkToRegister, FALSE

    .IF gradeAverage > 350
        mov OkToRegister, TRUE
    .ELSEIF (gradeAverage > 250) && (credits <= 16)
        mov OkToRegister, TRUE
    .ELSEIF (credits <= 12)
        mov OkToRegister, TRUE
    .ENDIF

    call Crlf
    call WaitMsg
    exit
main ENDP

END
4). 使用.REPEAT.WHILE創(chuàng)建循環(huán)
  • 格式
; .REPEAT 指令
.REPEAT
    statements
.UNTIL condition

; .WHILE 指令
.WHILE condition
    statements
.ENDW
  • .REPEAT 示例
mov eax,0
.REPEAT
    inc eax
    call WriteDec
    call Crlf
.UNTIL eax == 10
  • .WHILE 示例
mov eax,0
.WHILE eax < 10
    inc eax
    call WriteDec
    call Crlf
.ENDW
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柴梆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子终惑,更是在濱河造成了極大的恐慌绍在,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異偿渡,居然都是意外死亡臼寄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門溜宽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吉拳,“玉大人,你說我怎么就攤上這事适揉×粼埽” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵嫉嘀,是天一觀的道長炼邀。 經(jīng)常有香客問我,道長剪侮,這世上最難降的妖魔是什么拭宁? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮票彪,結(jié)果婚禮上红淡,老公的妹妹穿的比我還像新娘。我一直安慰自己降铸,他們只是感情好在旱,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著推掸,像睡著了一般桶蝎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谅畅,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天登渣,我揣著相機與錄音,去河邊找鬼毡泻。 笑死胜茧,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的仇味。 我是一名探鬼主播呻顽,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼丹墨!你這毒婦竟也來了廊遍?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤贩挣,失蹤者是張志新(化名)和其女友劉穎喉前,沒想到半個月后没酣,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡卵迂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年裕便,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狭握。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡闪金,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出论颅,到底是詐尸還是另有隱情哎垦,我是刑警寧澤,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布恃疯,位于F島的核電站漏设,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏今妄。R本人自食惡果不足惜郑口,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盾鳞。 院中可真熱鬧犬性,春花似錦、人聲如沸腾仅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽推励。三九已至鹤耍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間验辞,已是汗流浹背稿黄。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留跌造,地道東北人杆怕。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像壳贪,于是被迫代替她去往敵國和親陵珍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351