实验10
大家帮忙看看有没有可以优化的地方{:5_111:}
assume cs:code
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995';年份
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514;84
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000;收入
dw 3,7,9,13,28,38,130,220,476,778,1001,1441,2258,2793,4037,5635,8226,11542,14430,15257,17800;人数168
db 16 dup(0);
data ends
stack segment
dw 16 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h
mov ax,data
mov ds,ax
mov bp,sp
sub sp,4
mov word ptr ,0
mov word ptr ,00001111b
mov cx,21
mov bx,0 ;w类型
mov si,210 ;dw类型
mov di,0 ;行数
;d 8 /20
s1: push cx
mov byte ptr ,15
mov ax,
mov dx,
mov ,ax
mov ,dx
mov byte ptr ,0
mov dx,
mov cl,
call show_str
mov ax,
mov dx,
call dtoc
add byte ptr ,15
mov dx,
mov cl,
call show_str
mov cx,
mov dx,
call divdw
call dtoc
add byte ptr ,30
mov dx,
mov cl,
call show_str
mov ax,
mov dx,0
call dtoc
sub byte ptr ,15
mov dx,
mov cl,
call show_str
pop cx
add bx,4
add di,2
inc byte ptr
loop s1
mov ax,4c00h
int 21h
;除法
;dx:ax/cx
;dx:ax,cx
divdw: push bp
mov bp,sp
push ax
mov ax,dx
mov dx,0
div cx
push ax
mov ax,
div cx
mov cx,dx
pop dx
mov sp,bp
pop bp
ret
;显示字符串
;dh 行号,dl列号
;cl 颜色
show_str: push es
push di
push si
push cx
push ax
mov ax,0b800h
mov es,ax
mov ax,00a0h
mul dh
mov di,ax
mov ax,2
mul dl
add di,ax
mov al,cl
mov ch,0
check: mov cl,
jcxz ok_show_str
mov es:,cl
mov es:,al
add di,2
inc si
jmp check
ok_show_str:pop ax
pop cx
pop si
pop di
pop es
ret
;将16进制转化为10进制字符串
;dx:ax,ds:si
dtoc: push si
push di
push dx
push ax
push cx
mov di,si
s_dtoc: mov cx,10
call divdw
add cl,30h
mov ,cl
inc si
push cx
mov cx,ax
jcxz ok_dtoc
pop cx
jmp s_dtoc
ok_dtoc:pop cx
mov byte ptr ,0
mov ax,si
sub ax,di
mov cl,2
div cl
dec si
mov cl,al
jcxz done_dtoc
s1_dtoc:mov al,
mov ah,
mov ,ah
mov ,al
inc di
dec si
loop s1_dtoc
done_dtoc: pop cx
pop ax
pop dx
pop di
pop si
ret
code ends
end start assume cs:code
data segment
db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995';年份
dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514;84
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000;收入
dw 3,7,9,13,28,38,130,220,476,778,1001,1441,2258,2793,4037,5635,8226,11542,14430,15257,17800;人数168
db 16 dup(0);
data ends
stack segment
dw 16 dup(0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h
mov ax,data
mov ds,ax
mov bp,sp
sub sp,4
mov word ptr ,0
mov word ptr ,00001111b
mov cx,21
mov bx,0 ;w类型
mov si,210 ;dw类型
mov di,0 ;行数
s1: push cx
mov byte ptr ,15
mov ax,
mov dx,
mov ,ax
mov ,dx
mov byte ptr ,0
mov dx,
mov cl,
call show_str
mov ax,
mov dx,
call dtoc
add byte ptr ,15
mov dx,
mov cl,
call show_str
mov cx,
mov dx,
call divdw
call dtoc
add byte ptr ,30
mov dx,
mov cl,
call show_str
mov ax,
mov dx,0
call dtoc
sub byte ptr ,15
mov dx,
mov cl,
call show_str
pop cx
add bx,4
add di,2
inc byte ptr
loop s1
mov ax,4c00h
int 21h
;除法
;dx:ax/cx
;dx:ax,cx
divdw: push bp
mov bp,sp
push ax
mov ax,dx
mov dx,0
div cx
push ax
mov ax,
div cx
mov cx,dx
pop dx
mov sp,bp
pop bp
ret
;显示字符串
;dh 行号,dl列号
;cl 颜色
show_str: push es
push di
push si
push cx
push ax
mov ax,0b800h
mov es,ax
mov ax,00a0h
mul dh
mov di,ax
mov ax,2
mul dl
add di,ax
mov al,cl
mov ch,0
check: mov cl,
jcxz ok_show_str
mov es:,cl
mov es:,al
add di,2
inc si
jmp check
ok_show_str:pop ax
pop cx
pop si
pop di
pop es
ret
;将16进制转化为10进制字符串
;dx:ax,ds:si
dtoc: push si
push di
push dx
push ax
push cx
mov di,si
s_dtoc: mov cx,10
call divdw
add cl,30h
mov ,cl
inc si
push cx
mov cx,ax
jcxz ok_dtoc
pop cx
jmp s_dtoc
ok_dtoc:pop cx
mov byte ptr ,0
mov ax,si
sub ax,di
mov cl,2
div cl
dec si
mov cl,al
jcxz done_dtoc
s1_dtoc:mov al,
mov ah,
mov ,ah
mov ,al
inc di
dec si
loop s1_dtoc
done_dtoc: pop cx
pop ax
pop dx
pop di
pop si
ret
code ends
end start 实验10代码优化建议
[*]数据段优化
建议用标签+offset代替硬编码偏移量(如210、168等)。例如:
year db '1975','1976'... ;84字节
incomedd 16,22... ;84字节
staff dw 3,7... ;42字节
bufferdb 16 dup(0)
后续用mov si,offset staff代替mov si,210
[*]堆栈平衡问题
divdw子程序中:
mov ax, ; 这里原代码不完整,应改为:
mov ax, ; 恢复原始ax值
建议改为更安全的堆栈操作:
divdw:
push ax ; 保存原始ax
mov ax,dx ; 高16位给ax
xor dx,dx ; dx清零
div cx ; ax=H/N, dx=H%N
push ax ; 保存商高位
pop ax ; 恢复ax为原始低16位
div cx ; ax=低16位/N, dx=最终余数
mov cx,dx ; 余数存入cx
pop dx ; 恢复商高位到dx
ret
[*]显示逻辑优化
四次show_str调用存在重复参数设置,建议:
mov dh, [行号]
mov dl, [列号]
mov cl, [颜色]
; 用循环统一处理四列
[*]字符串反转改进
dtoc中的反转循环可优化为:
reverse:
mov al,
xchg al,
mov , al
inc di
dec si
loop reverse
[*]关键寄存器保护
在show_str和dtoc中缺少对ds寄存器的保护,建议添加:
push ds
popds ; 在子程序返回前恢复
[*]注释增强
建议添加关键步骤注释:
; 输入:dx:ax=32位数
; 输出:ds:si=字符串首地址
dtoc proc
...
其他注意事项
[*]数据段中收入数据有两行dd,疑似定义错误,应合并为连续数据
[*]建议用lea si,year代替mov si,0提升可读性
[*]除法前应添加cx非零检查,防止除零错误
优化后代码片段示例:
; 更安全的divdw
divdw proc
push bx
movbx,ax ; 保存低16位
movax,dx
xordx,dx ; 高16位/N
divcx
xchg ax,bx ; 商高存bx, 低16位给ax
divcx ; ax=商低, dx=余数
movcx,dx ; 余数
movdx,bx ; 商高
popbx
ret
divdw endp
建议用计算器验证数据偏移量,并使用EQU定义常量提升可维护性:
YEAR_CNTEQU 21
INCOME_CNT EQU 21
STAFF_CNTEQU 21
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]