chunhuaqiuyue 发表于 2022-1-6 22:34:31

课程设计1,优雅实现,欢迎交流

本帖最后由 chunhuaqiuyue 于 2022-1-10 22:05 编辑

设计思想: 函数式调用,将call理解为符号,后面作为要做的动作
assume cs:code,ds:data,ss:stack

data segment
    ;years
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995'
    ; income
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ;stuff count
    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

stack segment
    dw 8 dup (0)
stack ends

code segment
start:
    call clear_screen

init:
    mov ax,data
    mov ds,ax
    mov ax,stack
    mov ss,ax
    mov ax,0b80ah
    mov es,ax

    mov bx,0 ; data address
    mov bp,0 ; screen address

    call output_year
    call output_income
    call output_stuff
    call output_avg_income

    mov ax,4c00h
    int 21h

; =============== output years =================
output_year:
    mov cx,21
    mov ah,2
    call outputYear
    ret

outputYear:
    mov al,
    mov es:,ax
    mov al,
    mov es:,ax
    mov al,
    mov es:,ax
    mov al,
    mov es:,ax

    add bx,4
    add bp,160 ; add a row of position

    loop outputYear
    ret

; ==============================================
output_avg_income:
    mov di,0 ; row
    mov cx,21
    mov bx,84 ; skip years
    mov si,168 ; skip years & income ; 21*4+21*4
    call outputAvgIncome
    ret

outputAvgIncome:
    mov ax,
    mov dx,
    mov bp,90 ; 45 cols

    push cx
    push bx
    call _outputAvgIncome
    pop bx
    pop cx

    add di,160
    add bx,4
    add si,2
    loop outputAvgIncome
    ret

_outputAvgIncome:
    mov cx,
    call divdw
    call _print_num
    ret

; ==============================================
output_stuff:
    mov di,0 ; row
    mov cx,21
    call outputStuff
    ret

outputStuff:
    mov ax,
    mov bp,60 ; 30 cols

    push cx
    call _outputStuff
    pop cx

    add di,160
    add bx,2
    loop outputStuff
    ret

_outputStuff:
    mov cx,10

    div cx
    add dl,30h
    mov dh,2
    mov es:,dx
    mov dx,0
    mov cx,ax
    jcxz divRet
    sub bp,2
    jmp short _outputStuff

; ==============================================
output_income:
    mov di,0 ; row
    mov cx,21
    call outputIncome
    ret

outputIncome:
    mov ax,
    mov dx,
    mov bp,30 ; 2*4+22*2 = 15 cols

    push cx
    push bx
    call _print_num
    pop bx
    pop cx

    add di,160
    add bx,4
    loop outputIncome
    ret

divRet:
    ret

; ===============================================
clear_screen:
    mov ax,0b800h
    mov es,ax
    mov ax,0
    mov dx,0700h
    mov cx,1760

clearScreen:
    mov es:,ax
    add bx,2
    loop clearScreen
    ret

; ===============================================
divdw:
    mov bx,ax
    mov ax,dx
    mov dx,0

    div cx

    xor ax,bx
    xor bx,ax
    xor ax,bx

    div cx

    xor dx,bx
    xor bx,dx
    xor dx,bx

    mov cx,bx
    ret

; ===============================================
_print_num:
    ;; ax=L; dx=H
    mov cx,10
    mov bx,ax
    mov ax,dx
    mov dx,0;; 以上三步则是 计算 H/N, 之后ax=int(H/N), dx=rem(H/N)
    div cx
    ; 因为当前ax中存放的是 int(H/N),相当于存放的是高位的数据
    ; 所以下面这3个 xor 操作是将高位的值放到bx中,然后再将 L 的数据放到ax中
   
    xor ax,bx ; 交换 ax和bx 的值
    xor bx,ax ; 交换 ax和bx 的值
    xor ax,bx ; 交换 ax和bx 的值
    ; 交换的目的其实只是为了减少空间的使用,不使用多余的内存来存储数据
    div cx
    ; 这一步之后,存放的是 ax=(rem(H/N)*65536+L)/N 的结果
    ;                  dx=余数
    ; 将高位的结果放到dx中
    xor dx,bx
    xor bx,dx
    xor dx,bx

    mov cx,bx ; 将余数存入cx
    mov ch,2
    add cl,30h
    mov es:,cx
    mov cx,0
    or cx,dx
    or cx,ax
    jcxz divRet
    sub bp,2
    jmp short _print_num
; ===============================================

code ends

end start
页: [1]
查看完整版本: 课程设计1,优雅实现,欢迎交流