代码优化

u010794309 2016-11-21 11:05:08
设缓冲区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大小,这说明可能机器码并没有减少,不知道有哪位高手能给出最优化的代码?
...全文
735 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
他说了是学习目的...
csdnxinshou2 2016-11-24
  • 打赏
  • 举报
回复
这种程序用汇编语言。。。纯粹吃多了。。。
  • 打赏
  • 举报
回复
输出转换可以考虑使用AAM指令,转换8位整数到3位BCD只需要三条指令,比使用div要简单。 ; 假设数据在AL中 = 101 aam 100 ; db 0d4h, 64h mov bl,ah aam ; bl ah al = 1 0 1
u010794309 2016-11-23
  • 打赏
  • 举报
回复
你用了29号中断功能,居说这是一个未公开的DOS功能,这省略了把功能号送AH还有把AL送DL,这两条代码,在整个程序确实可以省略好几条代码,但我不希望show子程序用堆栈或者内存空间作为转换中介,我还是希望用寄存器,因为寄存器是最快的,虽然在本程序中没多大意义,但我只将它作为提高的方法。不知道可否有更好的思路或者算法?还有EXE转COM不是我想要的,因为这跟编程技巧没多大关系。
baidu_23107797 2016-11-22
  • 打赏
  • 举报
回复
PDATA DB 5 dup (0) MDATA DB 5 dup (0) 才是...
baidu_23107797 2016-11-22
  • 打赏
  • 举报
回复
这个不知算不算优化了,com档格式,代码59行, 大小125字节. exe - > com 用 exe2bin xxxx.exe xxxx.com

CODE_SEG SEGMENT
	ASSUME  CS:CODE_SEG,DS:CODE_SEG
        ORG     100H
begin:  jmp     short start
 DATA DB 38,-4,5,6,-7,8,-9,-110,-1,-32,-123,27,58,44,-12,0
 PDATA DB 5 (0)
 MDATA DB 5 (0)
START:	mov si,offset data
	mov di,offset PDATA
	mov bx,offset MDATA
	mov dx,0505h
next: 	lodsb
	or al,al
	jz next5
	jl next1
	dec dl
	js next3
	stosb
	jmp short next
next1: 	dec dh
	js next3
	mov [bx],al
	inc bx
next3: 	jmp short next
next5: 	mov si,offset PDATA
	mov di,10
next6:	lodsb
	mov bl,al
	test al,10000000b
	jz next7
	mov al,'-'
	int 29h
	neg bl
next7:	mov al,bl
	call show
	dec di
	jz over
	mov al,','
	int 29h
	jmp short next6
OVER:	MOV  AH,4CH
	INT 21H
show:	xor cx,cx 
	mov bx,10 
show1:	xor dx,dx 
	div bx ;ax /10 
	push dx ;保存
	inc cx ;累加个数
	or ax,ax ;是否已除尽
	jnz show1 ;不是,再除
	mov bl,cl ;存个数
show2:	pop ax  
	or al,30h ;转ascii
	int 29h ;print it
	loop show2 ;下一个
	ret
CODE_SEG ENDS
END  begin
zara 2016-11-22
  • 打赏
  • 举报
回复
可执行程序 2K ?用的什么链接程序啊,masm 出来的是 700 多字节嘛;且,前面有 512 字节的 dos exe 文件头,自己的实际内容才 200 多字节。
u010794309 2016-11-22
  • 打赏
  • 举报
回复
如果从多几个字节少几个字节的角度来看,这当然没必要优化,我本着学习好的编程技巧,任何大的程序都是由许多小的程序组成的。
我用的PWB集成开发环境(codeview)
  • 打赏
  • 举报
回复
这种代码没有必要优化,多几个字节少几个字节有什么影响?或者生成.com格式可以减少很多字节,按照zara说的就是剩下 200 多字节,如果非要卖弄技巧的话,我估计也可以优化到100多字节。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧