6.1 布尔和比较指令

 

操作 说明
AND 源操作数和目的操作数进行逻辑与操作
OR 源操作数和目的操作数进行逻辑或操作
XOR 源操作数和目的操作数进行逻辑异或操作
NOT 对目标操作数进行逻辑非操作
TEST 源操作数和目的操作数进行逻辑与操作,并适当地设置 CPU 标志位

 6.2.4 XOR指令

对 16 位整数来说,可以通过将其高字节和低字节进行异或运算来检测数的奇偶性:

mov ax,64Clh    ;0110 0100 1100 0001
xor ah, al            ;奇偶标志位置1 (偶)

将每个寄存器中的置 1 位(等于 1 的位)想象为一个 8 位集合中的成员。XOR 指令把两个集合交集中的成员清 0,并形成了其余位的并集。这个并集的奇偶性与整个 16 位整数的奇偶性相同。

 

6.2.8 设置和清除单个CPU状态标志

要将零标志位清零,就把操作数与 1 进行 OR 操作:

test al, 0           ;零标志位置 1
and al, 0           ;零标志位置 1
or al, 1              ;零标志位清零

TEST 指令不修改目的操作数,而 AND 指令则会修改目的操作数。若要符号标志位置 1,将操作数的最高位和 1 进行 OR 操作;若要清除符号标志位,则将操作数最高位和 0 进行 AND 操作:

or al, 80h         ;符号标志位置 1
and al, 7Fh       ;符号标志位清零

若要进位标志位置 1,用 STC 指令;清除进位标志位,用 CLC 指令:

stc                   ;进位标志位置 1
clc                   ;进位标志位清零

若要溢出标志位置 1,就把两个正数相加使之产生负的和数;若要清除溢出标志位,则将操作数和 0 进行 OR 操作:

mov al,7Fh       ; AL = +127
inc al                ; AL = 80h (-128), OF=1
or eax, 0           ; 溢出标志位清零

 

6.3 条件跳转

1.基于特定CPU标志值的跳转指令

基于零标志位、进位标志位、溢出标志位、奇偶标志位和符号标志位的跳转。

 

助记符 说明 标志位/寄存器 助记符 说明 标志位/寄存器
JZ 为零跳转 ZF=1 JNO 无溢出跳转 OF=0
JNZ 非零跳转 ZF=0 JS 有符号跳转 SF=1
JC 进位跳转 CF=1 JNS 无符号跳转 SF=0
JNC 无进位跳转 CF=0 JP 偶校验跳转 PF=1
JO 溢出跳转 OF=1 JNP 奇校验跳转 PF=0

 2.恒等性比较

助记符 说明
JE 相等跳转 (leftOp=rightOp)
JNE 不相等跳转 (leftOp M rightOp)
JCXZ CX=0 跳转
JECXZ ECX=0 跳转
JRCXZ RCX=0 跳转(64 位模式)

3.无符号数比较

助记符 说明 助记符 说明
JA 大于跳转(若 leftOp > rightOp) JB 小于跳转(若 leftOp < rightOp)
JNBE 不小于或等于跳转(与 JA 相同) JNAE 不大于或等于跳转(与 JB 相同)
JAE 大于或等于跳转(若 leftOp ≥ rightOp) JBE 小于或等于跳转(若 leftOp ≤ rightOp)
JNB 不小于跳转(与 JAE 相同) JNA 不大于跳转(与 JBE 相同)

 

4.有符号数比较

助记符 说明 助记符 说明
JG 大于跳转(若 leftOp > rightOp) JL 小于跳转(若 leftOp < rightOp)
JNLE 不小于或等于跳转(与 JG 相同) JNGE 不大于或等于跳转(与 JL 相同)
JGE 大于或等于跳转(若 leftOp ≥ rightOp) JLE 小于或等于跳转(若 leftOp ≤ rightOp)
JNL 不小于跳转(与 JGE 相同) JNG 不大于跳转(与 JLE 相同)

 

6.9编程练习

2.循环的实现

TITLE TEST PROJECT 

INCLUDE Irvine32.inc

.data
    array DWORD 10,60,20,33,72,89,56,65,72,18
    sample DWORD 50
    ArraySize DWORD LENGTHOF array
    index DWORD 0
    sum DWORD 0

.code
main PROC
    mov esi,ArraySize
    mov ebx,index
    mov edx,sample
    mov eax,sum
    .WHILE ebx < esi
    .IF array[ebx*TYPE array] <= edx
    add eax,array[ebx*TYPE array]
    mov sum,eax
    .ENDIF
    inc ebx
    .ENDW
    call WriteInt
    call DumpRegs
    call WaitMsg
    exit
main ENDP
END main

 

3.测验分数的评级(1)

TITLE TEST PROJECT 

INCLUDE Irvine32.inc

.data
    Msg BYTE 'Please input grade(0~100):',0
    Class BYTE 'A','B','C','D','F'

.code
main PROC
    mov edx,OFFSET Msg
    call WriteString
    call ReadDec
    .IF eax >= 90 && eax <= 100
        mov al,Class[0]
    .ELSEIF eax >= 80 && eax <= 89
        mov al,Class[1]
    .ELSEIF eax >= 70 && eax <= 79
        mov al,Class[2]
    .ELSEIF eax >= 60 && eax <= 69
        mov al,Class[3]
    .ELSEIF eax >= 0 && eax <= 59
        mov al,Class[4]
    .ENDIF
    call WriteChar
    call WaitMsg
    exit
main ENDP
END main

 

4.3.测验分数的评级(2)

TITLE TEST PROJECT 

INCLUDE Irvine32.inc

.data
    Msg BYTE 'Please input grade(0~100):',0
    Class BYTE 'A','B','C','D','F'
    Warning BYTE 'Input beyond range!',0


.code
main PROC
    .WHILE 1
        mov edx,OFFSET Msg
        call WriteString
        call ReadDec
        .IF eax >= 90 && eax <= 100
            mov al,Class[0]
        .ELSEIF eax >= 80 && eax <= 89
            mov al,Class[1]
        .ELSEIF eax >= 70 && eax <= 79
            mov al,Class[2]
        .ELSEIF eax >= 60 && eax <= 69
            mov al,Class[3]
        .ELSEIF eax >= 0 && eax <= 59
            mov al,Class[4]
        .ELSE
            mov edx,OFFSET Warning
            call WriteString
            jmp S
        .ENDIF
        call WriteChar
    S:
        call Crlf
        call WaitMsg
        call Clrscr
    .ENDW
    exit
main ENDP
END main

 

7.布尔计算器(1)

TITLE TEST PROJECT 

INCLUDE Irvine32.inc

.data
Info1 BYTE '(1)x AND y',13,10,
           '(2)x OR y',13,10,
           '(3)NOT x',13,10,
           '(4)x XOR y',13,10,
           '(5)Exit program',0
Ch1 BYTE 'AND',0
Ch2 BYTE 'OR',0
Ch3 BYTE 'AND',0
Ch4 BYTE 'AND',0
Ch5 BYTE 'Exit',0
Other BYTE 'Input error!',0
.code
main PROC
    mov edx,OFFSET Info1
    call WriteString
    call Crlf
    call ReadDec
    .IF eax == 1
        mov edx,OFFSET Ch1
        call WriteString
    .ELSEIF eax == 2
        mov edx,OFFSET Ch2
        call WriteString
    .ELSEIF eax == 3
        mov edx,OFFSET Ch3
        call WriteString
    .ELSEIF eax == 4
        mov edx,OFFSET Ch4
        call WriteString
    .ELSEIF eax == 5
        mov edx,OFFSET Ch5
        call WriteString
    .ELSE
        mov edx,OFFSET Other
        call WriteString
    .ENDIF
    call Crlf
    call WaitMsg
    exit
main ENDP
END main

 

8.布尔计算器(2)

TITLE TEST PROJECT 

INCLUDE Irvine32.inc

.data
Info1 BYTE '(1)x AND y',13,10,
           '(2)x OR y',13,10,
           '(3)NOT x',13,10,
           '(4)x XOR y',13,10,
           '(5)Exit program',0
Choosex BYTE 'Input x:',0
Choosey BYTE 'Input y:',0
Ch5 BYTE 'Exit',0
Other BYTE 'Input error!',0
.code
main PROC
    ;菜单
    mov edx,OFFSET Info1
    call WriteString
    call Crlf
    ;读取选择
    call ReadDec
    ;退出
    .IF eax == 5
        mov edx,OFFSET Ch5
        call WriteString
        jmp S
    ;超出选择范围
    .ELSEIF eax < 1 || eax > 5
        mov edx,OFFSET Other
        call WriteString
        jmp S
    .ENDIF
    push eax
    ;输入x
    mov edx,OFFSET Choosex
    call WriteString
    call ReadHex
    mov ebx,eax
    pop eax
    ;是否需要输入y
    .IF eax != 3
        push eax
        mov edx,OFFSET Choosey
        call WriteString
        call ReadHex
        mov edx,eax
        pop eax
    .ENDIF
    ;根据选择进行操作
    .IF eax == 1
        and ebx,edx
    .ELSEIF eax == 2
        or ebx,edx
    .ELSEIF eax == 3
        not ebx
    .ELSEIF eax == 4
        xor ebx,edx
    .ENDIF
    ;显示结果
    mov eax,ebx
    call WriteHex
S:
    call Crlf
    call WaitMsg
    exit
main ENDP
END main

 

9.自定义秘钥输入

TITLE Encryption Program

INCLUDE Irvine32.inc

KEYMAX = 128
BUFMAX = 128

.data
sPrompt BYTE "Enter the plain text:",0
sKey BYTE "Enter the Key:",0
sEncrypt BYTE "Cipher text:",0
sDecrypt BYTE "Decrypted:",0
key BYTE KEYMAX+1 DUP(0)
buffer BYTE BUFMAX+1 DUP(0)
KeySize DWORD ?
BufSize DWORD ?

.code
main PROC
    call InputTheStringAndKey
    call TranslateBuffer
    mov edx,OFFSET sEncrypt
    call DisplayMessage
    call TranslateBuffer
    mov edx,OFFSET sDecrypt
    call DisplayMessage
    
    call WaitMsg
    exit
main ENDP

InputTheStringAndKey PROC
    pushad
    ;待加密字符串输入提示
    mov edx,OFFSET sPrompt
    call WriteString
    ;输入读入缓存
    mov ecx,BUFMAX
    mov edx,OFFSET buffer
    call ReadString
    ;更新待加密字符串长度
    mov BufSize,eax
    call Crlf
    ;密钥输入提示
    mov edx,OFFSET sKey
    call WriteString
    ;输入读入缓存
    mov ecx,KEYMAX
    mov edx,OFFSET key
    call ReadString
    ;更新密钥长度
    mov KeySize,eax
    call Crlf
    popad
    ret
InputTheStringAndKey ENDP

DisplayMessage PROC
    pushad
    ;输出提示字符串
    call WriteString
    ;输出缓存区内容
    mov edx,OFFSET buffer
    call WriteString
    call Crlf
    call Crlf
    popad
    ret
DisplayMessage ENDP

TranslateBuffer PROC
    pushad
    mov ecx,BufSize
    mov esi,0
    mov edi,0
    ;外部循环--待加密字符串
Li:
    push ecx
    mov ecx,KeySize
    ;内部循环--密钥
Li2:
    mov al,key[edi]
    xor buffer[esi],al
    inc esi
    loop Li2

    pop ecx
    loop Li
    popad
    ret
TranslateBuffer ENDP
END main