汇编语言的艺术之三:基本认识
二、程式要条理通顺
1,在比较判断的过程中,邻近值不必连比。
CMP AL,0
JE ABCD0
CMP AL,1
JE ABCD1
CMP AL,2
JE ABCD2
..
应为:
CMP AL,1
JNE ABCD0
ABCD1:
..
在标题为ABCD0 中,再作:
JA ABCD2
这种做法端视时间效益而定,似此 ABCD1之速度最快。
2,未经慎思的流程:
ADD AX,4
ABCD:
STOSW
ADD AX,4
ADD DI,2
LOOP ABCD
..
稍稍动点脑筋,就好得多了:
ABCD:
ADD AX,4
STOSW
INC DI
INC DI
LOOP ABCD
..
3,错误的处理方式:
MOV BX,SI
ABCD:
MOV BX,[BX]
OR BX,BX
JZ ABCD1
MOV SI,BX
JMP ABCD
ABCD1:
LODSW
..
上例应该写成:
MOV BX,SI
ABCD:
LODSW
OR AX,AX
JZ ABCD1
MOV SI,BX
JMP ABCD
ABCD1:
..
4,错误的流程:
TEST AL,20H
JNZ ABCD
CALL CDEF[BX]
JMP SHORT ABCD1
ABCD:
CALL CDEF[BX+2]
ABCD1:
..
应该写成:
TEST AL,20H
JZ ABCD
INC BX
INC BX
ABCD:
CALL CDEF[BX]
ABCD1:
..
5,下面是时间的损失:
PUSH DI
MOV CX,BX
REP STOSB
POP DI
PUSH,POP 很费时间,应为:
MOV CX,BX
REP STOSB
SUB DI,BX
同理,很多时候稍稍想一下,就可省下一些指令:
PUSH CX
REP MOVSB
POP CX
SUB DX,CX
为什么不干脆些?
SUB DX,CX
REP MOVSB
6,有段程式,很有规律,但却极无效率:
X1:
TEST AH,1
JZ X2
MOV BUF1,BL
X2:
TEST AH,2
JZ X3
MOV BUF2,DX ; 凡双数用DX,单数用BL
X3:
TEST AH,4
JZ X4
MOV BUF3,BL
X4:
.. ; 以下各段与上述程式相似
X8:
..
这种金玉其表的程式,最没有实用价值,改的方法应由缓冲器着手,先安排成序列,由小而大如:
BUF1 DB ?
BUF2 DW ?
BUF3 DB ?
BUF4 DW ?
..
然后,程式改为:
MOV DI,OFFSET BUF1 ; 第一个缓冲器
MOV AL,BL
MOV CX,4
X1:
SHR AH,1
JZ X2
STOSB
X2:
SHR AH,1
JZ X3
MOV [DI],DX
INC DI
INC DI
X3:
LOOP X1
7,回路最怕千回百转,不畅不顺,如:
SUB AH,AH
ABCD:
CMP AL,BL
JB ABCD1
SUB AL,BL
INC AH
JMP ABCD
ABCD1:
..
以上 ABCD1这个入口是多余的,下面就好得多:
MOV AH,-1
ABCD:
INC AH
SUB AL,BL
JA ABCD
ADD AL,BL ; 还原
..
8,当处理字码时,需要字母的序数,有这样的写法:
CMP AL,60H
JA ABCD1
SUB AL,40H ; 大写字母
ABCD:
..
ABCD1:
SUB AL,60H ; 小写字母
JMP ABCD
要知道字母码的特色在于大写为 40H 至4AH,小写为60H 至6AH ,以上程式,其实只要一个指令就可以了:
AND AL,1FH
简单明瞭!
9,大多数的程式在程式师自己测试下很少发生错误,而一旦换一另个人执,就会发现错误百出。
其原因在于写程式者已经假定了正确的情况,当然不会以明知为错误的方式操作。可是换了一个人,没有先入为主的成见,很可能输入了「不正确」的资料,结果是问题丛生。
要知道真正的使用者,绝非设计者本人,在操作过程中,按键错误在所难免。这种错误应该在程式中事先加以检查,凡是输入资料有「正确、错误」之别者,错误性资料一定要事先加以排除。
这样做看起来似乎程式不够精简,可是正确的重要性远在精简之上。一旦发生了错误,再精简的程式也没有使 用价值。
此外,在程式中常有加、减的运算,这时也应该作正确性检查,否则会发生上述同样的问题。