代码优化
设缓冲区DATA中有一组单字节有符号数,以0为结束标示。写一个程序实现如下功能:把前5个正数依次送入缓冲区PDATA,把前5个负数依次送入缓冲区MDATA;如正数或负数不足5个,则用0补足。原程序如下:
MAX_COUNT=5
DSEG SEGMENT
DATA DB 38,-4,5,6,-7,8,-9,-110,-1,-32,-123,27,58,44,-12,0
PDATA DB MAX_COUNT DUP (?)
MDATA DB MAX_COUNT DUP (?)
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG
START:MOV AX,DSEG
MOV DS,AX
MOV CX,MAX_COUNT
MOV SI,OFFSET PDATA
MOV DI,OFFSET MDATA
MOV AL,0
NEXT1:MOV [SI],AL
MOV [DI],AL
INC SI
INC DI
LOOP NEXT1
XOR BX,BX
XOR SI,SI
XOR DI,DI
NEXT2:MOV AL,BYTE PTR DATA[BX]
INC BX
CMP AL,0
JZ OVER
JG PLUS
CMP DI,MAX_COUNT
JAE CONT
MOV MDATA[DI],AL
INC DI
JMP SHORT CONT
PLUS: CMP SI,MAX_COUNT
JAE CONT
MOV PDATA[SI],AL
INC SI
CONT: MOV AX,SI
ADD AX,DI
CMP AX,MAX_COUNT+MAX_COUNT
JB NEXT2
OVER: MOV AH,4CH
INT 21H
CSEG ENDS
END START
为了能把PDATA和MDATA内存单元的数字用ASII码显示出来,增加了SHOW子程序,完整程序如下:
MAX_COUNT=5
DSEG SEGMENT
DATA DB 38,-4,5,6,-7,8,-9,-110,-1,-32,-123,27,58,44,-12,0
PDATA DB MAX_COUNT DUP (?)
MDATA DB MAX_COUNT DUP (?)
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG
START:MOV AX,DSEG
MOV DS,AX
MOV CX,MAX_COUNT
MOV SI,OFFSET PDATA
MOV DI,OFFSET MDATA
MOV AL,0
NEXT1:MOV [SI],AL
MOV [DI],AL
INC SI
INC DI
LOOP NEXT1
XOR BX,BX
XOR SI,SI
XOR DI,DI
NEXT2:MOV AL,BYTE PTR DATA[BX]
INC BX
CMP AL,0
JZ OVER
JG PLUS
CMP DI,MAX_COUNT
JAE CONT
MOV MDATA[DI],AL
INC DI
JMP SHORT CONT
PLUS: CMP SI,MAX_COUNT
JAE CONT
MOV PDATA[SI],AL
INC SI
CONT: MOV AX,SI
ADD AX,DI
CMP AX,MAX_COUNT+MAX_COUNT
JB NEXT2
XOR SI,SI
MOV AX,DSEG
MOV DS,AX
RPDATA:XOR AX,AX
MOV AL,BYTE PTR PDATA[SI]
CALL SHOW
INC SI
CMP SI,MAX_COUNT
JB RPDATA
XOR DI,DI
MOV AX,DSEG
MOV DS,AX
RMDATA:MOV DL,2DH
MOV AH,2
INT 21H
XOR AX,AX
MOV AL,BYTE PTR MDATA[DI]
NEG AL
CALL SHOW
INC DI
CMP DI,MAX_COUNT
JB RMDATA
JMP OVER
SHOW PROC
CMP AL,9
JBE SN1
CMP AL,99
JBE SN2
MOV CH,10
DIV CH
SN3: ADD AH,30H
MOV BL,AH
MOV AH,0
DIV CH
ADD AH,30H
MOV BH,AH
ADD AL,30H
MOV AH,2
MOV DL,AL
INT 21H
MOV DL,BH
INT 21H
MOV DL,BL
INT 21H
JMP S
SN2: MOV CH,10
DIV CH
ADD AH,30H
MOV BH,AH
ADD AL,30H
MOV DL,AL
MOV AH,2
INT 21H
MOV DL,BH
INT 21H
JMP S
SN1: ADD AL,30H
MOV DL,AL
MOV AH,2
INT 21H
S: MOV DL,2CH
INT 21H
RET
SHOW ENDP
OVER: MOV AH,4CH
INT 21H
CSEG ENDS
END START
但是又觉得程序可以优化一下,程序修改如下:
MAX_COUNT=5
DSEG SEGMENT
DATA DB 38,-4,5,6,-7,8,-9,-110,-1,-32,-123,27,58,44,-12,0
PDATA DB MAX_COUNT DUP (?)
MDATA DB MAX_COUNT DUP (?)
DSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,DS:DSEG
START:MOV AX,DSEG
MOV DS,AX
MOV CX,MAX_COUNT
MOV SI,OFFSET PDATA
MOV DI,OFFSET MDATA
MOV AL,0
NEXT1:MOV [SI],AL
MOV [DI],AL
INC SI
INC DI
LOOP NEXT1
XOR BX,BX
XOR SI,SI
XOR DI,DI
NEXT2:MOV AL,BYTE PTR DATA[BX]
INC BX
CMP AL,0
JZ OVER
JG PLUS
CMP DI,MAX_COUNT
JAE CONT
MOV MDATA[DI],AL
INC DI
JMP SHORT CONT
PLUS: CMP SI,MAX_COUNT
JAE CONT
MOV PDATA[SI],AL
INC SI
CONT: MOV AX,SI
ADD AX,DI
CMP AX,MAX_COUNT+MAX_COUNT
JB NEXT2
XOR SI,SI
MOV AX,DSEG
MOV DS,AX
RPDATA:XOR AX,AX
MOV AL,BYTE PTR PDATA[SI]
CALL SHOW
INC SI
CMP SI,MAX_COUNT
JB RPDATA
XOR DI,DI
MOV AX,DSEG
MOV DS,AX
RMDATA:MOV DL,2DH
MOV AH,2
INT 21H
XOR AX,AX
MOV AL,BYTE PTR MDATA[DI]
NEG AL
CALL SHOW
INC DI
CMP DI,MAX_COUNT
JB RMDATA
JMP OVER
SHOW PROC
MOV CH,10
CMP AL,9
JBE SN1
CMP AL,99
JBE SN2
SN3: DIV CH
MOV BL,AH
DIV CH
MOV BH,AH
CALL SN
MOV AL,BH
CALL SN
MOV AL,BL
CALL SN
JMP S
SN2: DIV CH
MOV BL,AH
CALL SN
MOV AL,BL
CALL SN
JMP S
SN1: CALL SN
S: MOV DL,2CH
INT 21H
RET
SHOW ENDP
SN PROC
MOV DL,AL
ADD DL,30H
MOV AH,2
INT 21H
RET
SN ENDP
OVER: MOV AH,4CH
INT 21H
CSEG ENDS
END START
好像源程序是小了1K,但可执行程序同样是2K大小,这说明可能机器码并没有减少,不知道有哪位高手能给出最优化的代码?