王爽 汇编 课设1

使用temp空间来暂存每一行要显示的字符, 然后调用show_str子程序 进行显示
外层21次循环
难点:dd段的数字太大,无法简单进行除10存储, 需要借助div_d 大除法的子程序(更改的),

assume cs:code,ds:table,ss:stack
stack segment
    db 32 dup (0)
stack ends
table segment 
    db 81 dup(0)   ; temp空间
    ; 81 * 1 = 81 byte
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995'
    ; 21 * 4 = 84 byte
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514   ; 12
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ; 21 * 4 = 84 byte
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800
    ; 21 * 2 = 42 byte
    db 1,0,0,0,0   ;  循环的第几,年的第几,钱的第几,人的第几,当前temp空间的指向
    ; 5 * 1 = 5 byte
table ends
code segment
start:
    mov ax,stack
    mov ss,ax
    mov sp,32

    mov ax,table  ; 原始数据
    mov ds,ax

    mov bx,0   ; 年的计数
    mov cx,21

    main_loop:
        push cx

        ; ds:[84+84+42+5] 是temp区域
        ; ==========================
        ; 显示4列        

        mov cx,4
        mov bl,ds:[81+84+84+42][1]  ; 年的字节在哪 
        mov bh,0
        mov si,0
        start_s1:
            mov dl, ds:81[bx]   ; 记得跳过81byte
            mov ds:[si],dl
            inc bx
            inc si
            loop start_s1

        mov al,4
        mov ds:[81+84+84+42][4],al

        ; ================  空格  =================

        mov cx,4        ; 空格数量
        ; mov dl,ds:[81+84+84+42][4]
        call add_space      ; 存储空格

        ; add dl,4
        ; mov ds:[81+84+84+42][4],dl   ; temp扩增了

        ; =================== 收入 ==================
        ; 显示10列        

        mov bl,ds:[81+84+84+42][2]  ; 收入的字节在哪 
        mov bh,0
        mov ax,ds:[81+84][bx]
        mov dx,ds:[81+84][bx+2]
        
        mov bl,ds:[81+84+84+42][4]      
        mov bh,0
        mov si,bx                  ;  存到 ds:[..] 中
        call dtoc

        add bl,10
        mov ds:[81+84+84+42][4],bl   ; temp扩增了
        
        ; ================  空格  =================

        mov cx,4        ; 空格数量
        call add_space      ; 存储空格

        ; =============  人数 ========================
        ; 显示6列        


        mov bl,ds:[81+84+84+42][3]  ; 人数bx位置
        mov bh,0
        mov ax,ds:[81+84+84][bx]  ; 低位
        mov dx,0        ; 高位没有
        mov bl,ds:[81+84+84+42][4]      
        mov bh,0
        mov si,bx                  ;  存到 ds:[..] 中
        call dtoc

        add si,6
        mov ds:[81+84+84+42][4],si   ; temp扩增了

        ; ================  空格  =================

        mov cx,4        ; 空格数量
        call add_space      ; 存储空格

        ;  ======  人均收入  =======================
        ;6位
        mov bl,ds:[81+84+84+42][2]
        mov al,ds:[81+84+84+42][3]
        mov bh,0
        mov ah,0
        mov di,ax
        mov ax,ds:[81+84][bx]         ; 收入 低位
        mov dx,ds:[81+84][bx].[2]     ; 收入 高位
        div word ptr ds:[81+84+84][di] 

        ; mov ax,ax  ; 使用数字字符化,ax可以不动
        mov dx,0     ; 高位没有
        mov bl,ds:[81+84+84+42][4]      
        mov bh,0
        mov si,bx                  ;  存到 ds:[..] 中
        call dtoc

        add bl,6
        mov ds:[81+84+84+42][4],bl   ; temp扩增了

        ; ================  空格  =================
        mov cl,80
        sub cl,ds:[81+84+84+42][4]    ; 空格数量
        mov ch,0
        call add_space      ; 存储空格

        ; ==================== 显示  ================= 
        mov al,0
        mov bl,ds:[81+84+84+42][4]
        mov bh,0
        mov ds:[bx],al  ; 最后一位存个0

        mov si,0
        mov dh,ds:[81+84+84+42][0]  ; row
        mov dl,1                    ; column
        call show_str 


        ; ========  收尾   ===========
        mov al,ds:[81+84+84+42][0]   
        add ax,1
        mov ds:[81+84+84+42][0],al  ;更新循环次数

        mov al,ds:[81+84+84+42][1]
        add al,4
        mov ds:[81+84+84+42][1],al

        mov al,ds:[81+84+84+42][2]
        add al,4
        mov ds:[81+84+84+42][2],al

        mov al,ds:[81+84+84+42][3]
        add al,2
        mov ds:[81+84+84+42][3],al

        pop cx
        dec cx
        jcxz main_over
        jmp far ptr main_loop 
        ; loop main_loop   ;超长度

main_over:

    mov cx,25
    sub cx,21
    mov di,0
    over_s:
        push cx
        mov cx,80        ; 空格数量
        call add_space   

        mov si,0
        mov dh,ds:[81+84+84+42][0].[di]  ; row
        mov dl,1                         ; column
        call show_str 
        
        pop cx
        loop over_s

    mov ax,4c00h
    int 21h    
; -------------------------------------------
add_space:
    push si
    push ax
    push dx
    push cx

    mov dl,ds:[81+84+84+42][4]

    ; cx => 空格个数
    ; dl => 第几列
    mov dh,0
    mov si,dx
    mov al,' '
    start_s2:
        mov ds:[si],al
        add si,1
        loop start_s2

    pop cx    ; 先把cx复原
    
    add dl,cl
    mov ds:[81+84+84+42][4],dl   ; temp扩增了
    
    pop dx
    pop ax
    pop si
    ret
; ------------------------------------------
dtoc:
    ; in   ax 低位    dx 高位   
    ; out  ds:[si]   ds:[si+2] 地址
    

    push ax
    push bx
    push cx
    push dx


    mov bx,0   ;记录位数
    run1:
        mov cx,10  ; 除数
        call divdw

        ; 处理                
        add cl,'0'  ; 变成字符
        mov ch,0
        push cx     ; 倒得入栈
        inc bx
        
        push dx    ; 备份dx,这是高位
        or dx,ax   ; 判断作为商的ax和dx为0吗
        mov cx,dx  ; 给cx 判断结束吗
        
        pop dx
        jcxz ok1  ; 除法结束
        jmp run1 


    ok1:
        ; ==== 开始写入 =====
        mov cx,bx
        mov dx,bx
        mov bx,si    ; 从ds:[si]  开始放字符
        dtoc_s1:
            pop ds:[bx]
            inc bx
            loop dtoc_s1

        mov cx,10     ; dd 最大可能用10byte
        sub cx,dx   
        jcxz dtoc_s3
        dtoc_s2:     ; 填充空格
            mov al,' '
            mov ds:[bx],al
            inc bx
            loop dtoc_s2 
        dtoc_s3:
        mov al,0
        mov ds:[bx],al


        pop dx    
        pop cx
        pop bx
        pop ax  
        ret
;----------------------------------------------------
divdw:
    ; in :  被除数  ax:low 16  dx:high 16   除数 cx
    ; out:  商     ax:low 16  dx:high 16   余数 cx 
    push bx  
    mov bx,ax  ;  backup 被除数 low 16

    mov ax,dx
    mov dx,0   ;  no high 
    div cx 

    push ax    ; save high 16 of result

    mov ax,bx  ; original 被除数 low 16
    mov dx,dx  ;  上一次的余数就是这一次的高位
    div cx

    mov cx,dx  ; 余数
    pop dx     ; high 16

    pop bx
    ret

; --------------------------------------------------

show_str:
    ; 显示 ds:[si] 中的 到0结束
    push dx
    push cx
    push ax
    push bx
    push si   

    mov cl,2  ; color

    mov ax,0b800h
    mov es,ax
    mov al,160
    mul dh
    mov bx,ax  ; calculate row

    mov dh,0
    add dx,dx  
    sub dx,2
    add bx,dx  ; add the column
    mov al,cl  ; color
    show_str_s1:
        mov cl,ds:[si]
        mov ch,0
        jcxz show_str_ok
        mov ch,al
        mov es:[bx],cx

        add si,1
        add bx,2
        jmp show_str_s1

    show_str_ok:
        pop si
        pop bx
        pop ax
        pop cx
        pop dx
        ret

code ends
end start

第一版耗时10小时
优化花费2小时

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值