FFFa 发表于 2025-5-6 14:40:58

实验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

FFFa 发表于 2025-5-6 14:42:27

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

FishC 发表于 2025-5-6 14:42:49

实验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]
查看完整版本: 实验10