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