在 ADR 开始的连续单元,存放三个16位无符号数 A,B,C。
数据定义:
ADR DW 3257H, 5891H, 0B24H
FLAG DB ?
要求:
若A、B、C同时为偶数,将 FLAG 单元设置为1;
若同时为奇数,将 FLAG 单元置0;
否则FLAG单元置全1。
编制汇编程序完成上述操作。
题目链接:http://zhidao.baidu.com/question/680336184056922132.html
---------------------------
分析:
题目的要求,可以写成下面的形式。
--全为偶,FLAG置1
--全为奇,FLAG置0
--奇偶皆有则FLAG单元置全1
如果这个序列都是奇数,就必须全部数据都检测一遍,才能确定它们全部都是奇数;
如果这个序列都是偶数,也是必须把全部数据都检测一遍。
但是,判断序列中,是不是也有奇数、也有偶数,这可就简单了。
比如,把第一个数,判断出来了,它是奇数,判断第二个数时,如果发现它是偶数,
那么,奇偶都存在的结论,这就已经出来了。还有必要继续判断吗?
这就是说,判断奇、偶都存在,就很简单,很有可能提前结束程序。不需要把全部数据都检测一遍。
做而论道就是按照这个思路,编写了如下的程序。
DATAS SEGMENT
; ADR DW 3257H, 5891H, 0B24H
ADR DW 325CH, 5890H, 0B24H
FLAG DB ?
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
MOV FLAG, 0FFH ;先假设奇偶皆有
TEST WORD PTR [ADR], 1
JNE QI1
;-----------------------------
OU1:
TEST WORD PTR [ADR + 2], 1
JE OU2
JMP EXIT
OU2:
TEST WORD PTR [ADR + 4], 1
JE OU3
JMP EXIT
;-----------------------------
QI1:
TEST WORD PTR [ADR + 2], 1
JNE QI2
JMP EXIT
QI2:
TEST WORD PTR [ADR + 4], 1
JNE QI3
JMP EXIT
;-----------------------------
OU3:
INC FLAG
QI3:
INC FLAG
EXIT:
MOV AH, 4CH
INT 21H
CODES ENDS
END START
程序中,首先判断第一个数字的奇偶性,为奇则转移,转移到 QI1 后,再继续检测后面的数据。
一旦发现检测到了偶数,就立即跳到结束程序的位置。
如果第一个数字是偶数,那么后面就连续检测数据都是否为奇数,为奇数则转到结束。
如果都是奇数(或都是偶数),那就一个一个检测吧,把全部数据都检测一遍,全奇(全偶)的结论也就出来了。
当得出结论后,对 FLAG 赋值时,做而论道写的也相当的简单,用了两条加一的指令,就代替了传送数据再转移的写法。
-----------------------------
做而论道的编程思路虽然比较好,但是提问者并没有理解。
他选择了一个“全部检测”的程序。
这个程序,确实,也是正确的。
它可以检测数据的奇偶个数的特点,也可以给 FLAG 正确的赋值。
但是,它把数据全部检测了一遍,把其中的偶数个数得出来了。
然后,再把这个偶数的个数和总数比较,如果相同,那就是说:全都是偶数。
否则,再判断这个偶数的个数,是 0 吗?如果是,那就是说:全都是奇数。
再否则,就是奇偶都有。
-----------------------------