鱼C论坛

 找回密码
 立即注册
查看: 61|回复: 2

[技术交流] 实验10

[复制链接]
发表于 前天 14:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

大家帮忙看看有没有可以优化的地方

  1. assume cs:code
  2. data segment
  3.         db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995';年份
  4.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514;84
  5.         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000;收入
  6.         dw 3,7,9,13,28,38,130,220,476,778,1001,1441,2258,2793,4037,5635,8226,11542,14430,15257,17800;人数168
  7.         db 16 dup(0);
  8. data ends

  9. stack segment
  10.         dw 16 dup(0)
  11. stack ends

  12. code segment
  13.         start:                mov ax,stack
  14.                                 mov ss,ax
  15.                                 mov sp,20h
  16.                                 mov ax,data
  17.                                 mov ds,ax
  18.                                 mov bp,sp
  19.                                 sub sp,4
  20.                                 mov word ptr [bp-2],0
  21.                                 mov word ptr [bp-4],00001111b
  22.                                 mov cx,21
  23.                                 mov bx,0        ;w类型
  24.                                 mov si,210        ;dw类型
  25.                                 mov di,0        ;行数       
  26.                                 ;d 8 /20
  27.                         s1:        push cx
  28.                        
  29.                                 mov byte ptr [bp-2],15
  30.                                 mov ax,[bx]
  31.                                 mov dx,[bx+2]
  32.                                 mov [si],ax
  33.                                 mov [si+2],dx
  34.                                 mov byte ptr [si+4],0
  35.                                 mov dx,[bp-2]
  36.                                 mov cl,[bp-4]
  37.                                 call show_str
  38.                                
  39.                                 mov ax,[bx+84]
  40.                                 mov dx,[bx+86]
  41.                                 call dtoc
  42.                                 add byte ptr [bp-2],15
  43.                                 mov dx,[bp-2]
  44.                                 mov cl,[bp-4]
  45.                                 call show_str
  46.                                
  47.                                 mov cx,[di+168]
  48.                                 mov dx,[bx+86]
  49.                                 call divdw
  50.                                 call dtoc
  51.                                 add byte ptr [bp-2],30
  52.                                 mov dx,[bp-2]
  53.                                 mov cl,[bp-4]
  54.                                 call show_str
  55.                                
  56.                                 mov ax,[168+di]
  57.                                 mov dx,0
  58.                                 call dtoc
  59.                                 sub byte ptr [bp-2],15
  60.                                 mov dx,[bp-2]
  61.                                 mov cl,[bp-4]
  62.                                 call show_str
  63.                                
  64.                                 pop cx
  65.                                 add bx,4
  66.                                 add di,2
  67.                                 inc byte ptr [bp-1]
  68.                                 loop s1
  69.                                 mov ax,4c00h
  70.                                 int 21h
  71.         ;除法
  72.         ;dx:ax/cx
  73.         ;dx:ax,cx
  74.         divdw:                push bp
  75.                                 mov bp,sp
  76.                                 push ax
  77.                                 mov ax,dx
  78.                                 mov dx,0
  79.                                 div cx
  80.                                 push ax
  81.                                 mov ax,[bp-2]
  82.                                 div cx
  83.                                 mov cx,dx
  84.                                 pop dx
  85.                                 mov sp,bp
  86.                                 pop bp
  87.                                 ret
  88.         ;显示字符串
  89.         ;dh 行号,dl列号
  90.         ;cl 颜色
  91.         show_str:        push es
  92.                                 push di
  93.                                 push si
  94.                                 push cx
  95.                                 push ax
  96.                                 mov ax,0b800h
  97.                                 mov es,ax
  98.                                 mov ax,00a0h
  99.                                 mul dh
  100.                                 mov di,ax
  101.                                 mov ax,2
  102.                                 mul dl
  103.                                 add di,ax
  104.                                 mov al,cl
  105.                                 mov ch,0
  106.                 check:        mov cl,[si]
  107.                                 jcxz ok_show_str
  108.                                 mov es:[di],cl
  109.                                 mov es:[di+1],al
  110.                                 add di,2
  111.                                 inc si
  112.                                 jmp check
  113.         ok_show_str:pop ax
  114.                                 pop cx
  115.                                 pop si
  116.                                 pop di
  117.                                 pop es
  118.                                 ret
  119.         ;将16进制转化为10进制字符串
  120.         ;dx:ax,ds:si
  121.         dtoc:                push si
  122.                                 push di
  123.                                 push dx
  124.                                 push ax
  125.                                 push cx
  126.                                 mov di,si
  127.                 s_dtoc:        mov cx,10
  128.                                 call divdw
  129.                                 add cl,30h
  130.                                 mov [si],cl
  131.                                 inc si
  132.                                 push cx
  133.                                 mov cx,ax
  134.                                 jcxz ok_dtoc
  135.                                 pop cx
  136.                                 jmp s_dtoc
  137.                 ok_dtoc:pop cx
  138.                                 mov byte ptr [si],0
  139.                                 mov ax,si
  140.                                 sub ax,di
  141.                                 mov cl,2
  142.                                 div cl
  143.                                 dec si
  144.                                 mov cl,al
  145.                                 jcxz done_dtoc
  146.                 s1_dtoc:mov al,[di]
  147.                                 mov ah,[si]
  148.                                 mov [di],ah
  149.                                 mov [si],al
  150.                                 inc di
  151.                                 dec si
  152.                                 loop s1_dtoc
  153.         done_dtoc:        pop cx
  154.                                 pop ax
  155.                                 pop dx
  156.                                 pop di
  157.                                 pop si
  158.                                 ret
  159. code ends

  160. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 前天 14:42 | 显示全部楼层
  1. assume cs:code
  2. data segment
  3.         db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995';年份
  4.         dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514;84
  5.         dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000;收入
  6.         dw 3,7,9,13,28,38,130,220,476,778,1001,1441,2258,2793,4037,5635,8226,11542,14430,15257,17800;人数168
  7.         db 16 dup(0);
  8. data ends

  9. stack segment
  10.         dw 16 dup(0)
  11. stack ends

  12. code segment
  13.         start:                mov ax,stack
  14.                                 mov ss,ax
  15.                                 mov sp,20h
  16.                                 mov ax,data
  17.                                 mov ds,ax
  18.                                 mov bp,sp
  19.                                 sub sp,4
  20.                                 mov word ptr [bp-2],0
  21.                                 mov word ptr [bp-4],00001111b
  22.                                 mov cx,21
  23.                                 mov bx,0        ;w类型
  24.                                 mov si,210        ;dw类型
  25.                                 mov di,0        ;行数       
  26.                         s1:        push cx
  27.                        
  28.                                 mov byte ptr [bp-2],15
  29.                                 mov ax,[bx]
  30.                                 mov dx,[bx+2]
  31.                                 mov [si],ax
  32.                                 mov [si+2],dx
  33.                                 mov byte ptr [si+4],0
  34.                                 mov dx,[bp-2]
  35.                                 mov cl,[bp-4]
  36.                                 call show_str
  37.                                
  38.                                 mov ax,[bx+84]
  39.                                 mov dx,[bx+86]
  40.                                 call dtoc
  41.                                 add byte ptr [bp-2],15
  42.                                 mov dx,[bp-2]
  43.                                 mov cl,[bp-4]
  44.                                 call show_str
  45.                                
  46.                                 mov cx,[di+168]
  47.                                 mov dx,[bx+86]
  48.                                 call divdw
  49.                                 call dtoc
  50.                                 add byte ptr [bp-2],30
  51.                                 mov dx,[bp-2]
  52.                                 mov cl,[bp-4]
  53.                                 call show_str
  54.                                
  55.                                 mov ax,[168+di]
  56.                                 mov dx,0
  57.                                 call dtoc
  58.                                 sub byte ptr [bp-2],15
  59.                                 mov dx,[bp-2]
  60.                                 mov cl,[bp-4]
  61.                                 call show_str
  62.                                
  63.                                 pop cx
  64.                                 add bx,4
  65.                                 add di,2
  66.                                 inc byte ptr [bp-1]
  67.                                 loop s1
  68.                                 mov ax,4c00h
  69.                                 int 21h
  70.         ;除法
  71.         ;dx:ax/cx
  72.         ;dx:ax,cx
  73.         divdw:                push bp
  74.                                 mov bp,sp
  75.                                 push ax
  76.                                 mov ax,dx
  77.                                 mov dx,0
  78.                                 div cx
  79.                                 push ax
  80.                                 mov ax,[bp-2]
  81.                                 div cx
  82.                                 mov cx,dx
  83.                                 pop dx
  84.                                 mov sp,bp
  85.                                 pop bp
  86.                                 ret
  87.         ;显示字符串
  88.         ;dh 行号,dl列号
  89.         ;cl 颜色
  90.         show_str:        push es
  91.                                 push di
  92.                                 push si
  93.                                 push cx
  94.                                 push ax
  95.                                 mov ax,0b800h
  96.                                 mov es,ax
  97.                                 mov ax,00a0h
  98.                                 mul dh
  99.                                 mov di,ax
  100.                                 mov ax,2
  101.                                 mul dl
  102.                                 add di,ax
  103.                                 mov al,cl
  104.                                 mov ch,0
  105.                 check:        mov cl,[si]
  106.                                 jcxz ok_show_str
  107.                                 mov es:[di],cl
  108.                                 mov es:[di+1],al
  109.                                 add di,2
  110.                                 inc si
  111.                                 jmp check
  112.         ok_show_str:pop ax
  113.                                 pop cx
  114.                                 pop si
  115.                                 pop di
  116.                                 pop es
  117.                                 ret
  118.         ;将16进制转化为10进制字符串
  119.         ;dx:ax,ds:si
  120.         dtoc:                push si
  121.                                 push di
  122.                                 push dx
  123.                                 push ax
  124.                                 push cx
  125.                                 mov di,si
  126.                 s_dtoc:        mov cx,10
  127.                                 call divdw
  128.                                 add cl,30h
  129.                                 mov [si],cl
  130.                                 inc si
  131.                                 push cx
  132.                                 mov cx,ax
  133.                                 jcxz ok_dtoc
  134.                                 pop cx
  135.                                 jmp s_dtoc
  136.                 ok_dtoc:pop cx
  137.                                 mov byte ptr [si],0
  138.                                 mov ax,si
  139.                                 sub ax,di
  140.                                 mov cl,2
  141.                                 div cl
  142.                                 dec si
  143.                                 mov cl,al
  144.                                 jcxz done_dtoc
  145.                 s1_dtoc:mov al,[di]
  146.                                 mov ah,[si]
  147.                                 mov [di],ah
  148.                                 mov [si],al
  149.                                 inc di
  150.                                 dec si
  151.                                 loop s1_dtoc
  152.         done_dtoc:        pop cx
  153.                                 pop ax
  154.                                 pop dx
  155.                                 pop di
  156.                                 pop si
  157.                                 ret
  158. code ends

  159. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 前天 14:42 | 显示全部楼层
实验10代码优化建议

  • 数据段优化
    建议用标签+offset代替硬编码偏移量(如210、168等)。例如:

    1. year    db '1975','1976'... ;84字节
    2. income  dd 16,22...          ;84字节
    3. staff   dw 3,7...            ;42字节
    4. buffer  db 16 dup(0)
    复制代码

    后续用mov si,offset staff代替mov si,210
  • 堆栈平衡问题
    divdw子程序中:

    1. mov ax, [bp-2] ; 这里原代码不完整,应改为:
    2. mov ax, [bp-2] ; 恢复原始ax值
    复制代码

    建议改为更安全的堆栈操作:

    1. divdw:
    2.     push ax        ; 保存原始ax
    3.     mov ax,dx      ; 高16位给ax
    4.     xor dx,dx      ; dx清零
    5.     div cx         ; ax=H/N, dx=H%N
    6.     push ax        ; 保存商高位
    7.     pop ax         ; 恢复ax为原始低16位
    8.     div cx         ; ax=低16位/N, dx=最终余数
    9.     mov cx,dx      ; 余数存入cx
    10.     pop dx         ; 恢复商高位到dx
    11.     ret
    复制代码

  • 显示逻辑优化
    四次show_str调用存在重复参数设置,建议:

    1. mov dh, [行号]
    2. mov dl, [列号]
    3. mov cl, [颜色]
    4. ; 用循环统一处理四列
    复制代码

  • 字符串反转改进
    dtoc中的反转循环可优化为:

    1. reverse:
    2.     mov al, [di]
    3.     xchg al, [si]
    4.     mov [di], al
    5.     inc di
    6.     dec si
    7.     loop reverse
    复制代码

  • 关键寄存器保护
    show_str和[b]dtoc中缺少对ds寄存器的保护,建议添加:

    1. push ds
    2. pop  ds ; 在子程序返回前恢复
    复制代码

  • 注释增强
    建议添加关键步骤注释:

    1. ; 输入:dx:ax=32位数
    2. ; 输出:ds:si=字符串首地址
    3. dtoc proc
    4.     ...
    复制代码



其他注意事项
  • 数据段中收入数据有两行dd,疑似定义错误,应合并为连续数据
  • 建议用lea si,year代替mov si,0提升可读性
  • 除法前应添加cx非零检查,防止除零错误


优化后代码片段示例:

  1. ; 更安全的divdw
  2. divdw proc
  3.     push bx
  4.     mov  bx,ax   ; 保存低16位
  5.     mov  ax,dx
  6.     xor  dx,dx   ; 高16位/N
  7.     div  cx
  8.     xchg ax,bx   ; 商高存bx, 低16位给ax
  9.     div  cx       ; ax=商低, dx=余数
  10.     mov  cx,dx   ; 余数
  11.     mov  dx,bx   ; 商高
  12.     pop  bx
  13.     ret
  14. divdw endp
复制代码


建议用计算器验证数据偏移量,并使用EQU定义常量提升可维护性:

  1. YEAR_CNT  EQU 21
  2. INCOME_CNT EQU 21
  3. STAFF_CNT  EQU 21
复制代码


以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-8 08:39

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表