光头羊与喜强强 发表于 2020-8-11 09:39:54

课程设计1

感觉写得有点粗糙,看过的大佬也分享一下你们的写法
assume cs:codesg

data segment

        db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
        db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
        db '1993','1994','1995'
       
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
       
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
        dw 11542,14430,15257,17800
       
data ends

table segment
       
        db 21 dup('year summ ne ?? ')
       
table ends

codesg segment
       
        start:mov ax,data
        mov ds,ax
        mov ax,0b800h
        mov es,ax
        mov di,0
        mov si,0
        mov bx,0
        mov cx,21
        s:push cx
        call showstr
        add si,14h
        mov ax,054h
        mov dx,054h.2
        call dtoc
        add si,14h
        mov ax,0a8h
        mov dx,0
        call dtoc
        add si,14h
        push bx
        mov ax,054h
        mov dx,054h.2
        mov bx,0a8h
        call divdw
        call dtoc
        pop bx
        add si,64h
        add di,4
        add bx,2
       
        pop cx
        loop s
        mov ax,4c00h
        int 21h
       
        showstr:mov ax,
        mov es:,al
        mov es:.2,ah
        mov ax,.2
        mov es:.4,al
        mov es:.6,ah
        ret
       
        dtoc:
        push bx
        mov cx,0
        push cx
        s0:mov bx,10
        call divdw
        jcxz checklow
        s2:pop cx
        inc cx
        add bx,30h
        push bx
        push cx
        mov cx,10
        loop s0
       
        divdw:push ax
        mov ax,dx
        mov dx,0
        div bx
        mov cx,ax
        pop ax
        div bx
        mov bx,dx
        mov dx,cx
        ret
       
        checklow:mov cx,ax
        jcxz showdw
        mov cx,0
        jcxz s2
       
        showdw:pop cx
        inc cx
        add bx,30h
        push bx
        mov bx,0
        s1:pop ax
        mov es:,al
        add bx,2
        loop s1
        pop bx
        ret
       
codesg ends

end start


FGing 发表于 2021-3-23 14:46:58

对比楼主的代码加上注释,还加上了个人的理解(看了一天了有的地方还是不理解。。。)。
assume cs:codesg

a segment
dw 1975,1976,1977,1978,1979,1980,1981,1982,1983
dw 1984,1985,1986,1987,1988,1989,1990,1991,1992
dw 1993,1994,1995;42

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000        ;84

dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw 11542,14430,15257,17800        ;42

;dw 5,3,42,104,85,210,123,111,105,125,140,136,153,211,199,209,224,239,260
;dw 304,333        ;42

a ends

codesg segment
start:
        mov ax,a
        mov ds,ax                                 ;a段数据段地址做ds
        mov ax,0b800h                         ;显存地址做es
        mov es,ax

        mov si,0                                ;显存偏移
        mov di,0                                ;字符偏移(收入)
        mov bx,0                                ;字符偏移

        mov cx,21

ls:        push cx
        mov ax,                         ;第一组字符(年份),低16位
        mov dx,0                                 ;清零高16位
        call dtoc

        add si,14h
        mov ax,                        ;第二组字符(收入),低16位
        mov dx,                        ;高16位
        call dtoc

        add si,14h
        mov ax,                ;第三组字符(人数),低16位
        mov dx,0                                ;清零高16位
        call dtoc

        push bx                                 ;因为要用到所以保存
        add si,14h
        mov ax,                        ;第二组字符(收入),低16位
        mov dx,                        ;高16位
        mov bx,                ;人数字符
        call divdw                                ;除法
        call dtoc
        pop bx
        add si,100                                ;显存换行写入
        add bx,2                                ;下一个字符
        add di,4                                ;下一个收入字符
        pop cx
        loop ls

        mov ax,4c00h
        int 21h

dtoc:
        push bx                                ;保存bx要用作之后用做被除数
        mov cx,0                               ;初始化cx   
    push cx                                        ;保存cx做计次用

s0:       
        mov bx,10                         ;除法的被除数
        call divdw                                ;跳转到除法
        jcxz checklow                        ;divdw代码结束时才会回到这里,cx=0跳转checklow
s2:        pop cx                                ;恢复计次
        inc cx                                ;计次
        add bx,30h                        ;余,ascll码
        push bx                                 ;保存字符ascll码
        push cx                                 ;保存计次
        ;mov cx,10                        
        ;loop s0
        jmp short s0

divdw:                                        ;除法
        push ax                                ;保存ax,先除dx
        mov ax,dx                                ;dx的值给ax
        mov dx,0                                ;清零,余(dx)
        div bx                                ;ax除以bx,高16位/10
        mov cx,ax                                 ;商给cx
        pop ax                                ;还原ax
        div bx                                 ;ax/bx = 低16位/10
        mov bx,dx                         ;余给bx
        mov dx,cx                                 ;第一次除法的商给dx
        ret

checklow:                                         ;当divdw段代码执行完成时,到jcxz checklow并且cx=0时跳转到这
        mov cx,ax                                 ;ax是divdw子程序的商
        jcxz showdw                           ;当除法,商=0时跳转
        jmp short s2                        ;计算下一个 ,1975 →197
        ;mov cx,0
        ;jcxz s2

showdw:                                         ;做字符ascll码
        pop cx                                ;把保存的次数拿出来
        inc cx                                ;加上一次循坏(最后余的)
        add bx,30h                        ;divdw 的余,第一位数(1975的1)
        push bx                                 ;把每个数字的ascll保存在栈
        mov bx,0                                 ;清零bx s1要用做显存的偏移变量

s1:        pop ax                                 ;把数字的ascll码拿出来
        mov es:,al                 ;bx是定位下一个显存字符的变量,(00 00 00 = 00 )
        add bx,2                                 ;下一组显存数据(00 00 00 = 00 00 )
        loop s1
        pop bx

        ret
codesg ends
end start
页: [1]
查看完整版本: 课程设计1