拖着拖把去拖鞋 发表于 2023-2-21 17:02:18

课程设计1

本帖最后由 拖着拖把去拖鞋 于 2023-3-3 15:16 编辑

用了3个循环.改了几次,这次应该是可读性最好的了.欢迎指导
; 显示数据在显示器上
assume cs:code

data segment
   ; 21个年头
          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年来每一年的收入,偏移位置开头为54H
          dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
          dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
   ; 21年来每一年的雇员,偏移位置开头为A8H
          dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
          dw 11542,14430,15257,17800
   ; 存放每一年的人均收入,偏移地址开头为D2H
          dw 21 dup (0)
   ; 21行40列的输出字符串,偏移地址开头为FCH
          db 840 dup (20H)
   ;偏移地址开头为444H,分别是年份、收入、雇员、人均收入的偏移地址
          dw 0H,54H,0A8H,0D2H
   ;偏移地址开头为44cH,分别是年份、收入、雇员、人均收入字符串的偏移地址
          dw 0FCH,106H,110H,11AH
data ends

stack segment
         dw 8 dup (0)
stack ends

code segment
   start:            movax,data
                         movds,ax
                         movax,stack
                         movss,ax
                         movsp,32

                         movsi,54H                        ; 用于定位年收入
                         movdi,0A8H                     ; 用于定位年雇员
                         movbp,0D2H                     ; 用于定位人均收入
                         movcx,21
   ; l0用于计算年人均收入
   l0:               movax,ds:
                         movdx,ds:
                         movbx,ds:
                         divbx                            ; 计算年人均收入
                         movds:,ax                  ; 存入计算得出的人均收入
                         addsi,4
                         adddi,2
                         addbp,2
                         loop l0

                         movcx,21
   l1:               push cx
   ; 存入年份 start
                         movdi,ds:                  ; 存入即将要处理的年份的偏移地址
                         movsi,ds:                  ; 存入即将要写入数据的偏移地址
                         movax,ds:                  ; 存入即将要处理的年份
                         movds:,ax                  ; 将年份存入字符串
                         movax,ds:                  ; 存入即将要处理的年份
                         movds:,ax                  ; 将年份存入字符串
                         adddi,4                        ; 移到下一个要处理的年份
                         addsi,40                         ; 移到下一行,对应年份的位置
                         movds:,di                  ; 更新内存中的地址
                         movds:,si                  ; 更新内存中的地址
   ; 存入年份 end

   ; 存入收入 start
                         movdi,ds:                  ; 存入即将要处理的收入的偏移地址
                         movsi,ds:                  ; 存入即将要写入数据的偏移地址
                         movax,ds:
                         movdx,ds:
                         push si
                         call change_to_dec_init            ; 转换收入数据
                         popsi
                         adddi,4
                         addsi,40
                         movds:,di                  ; 更新内存中的地址
                         movds:,si                  ; 更新内存中的地址
                         movdx,0
   ; 存入收入 end

   ; 录入雇员 start
                         movdi,ds:
                         movsi,ds:                  ; 存入即将要写入数据的偏移地址
                         movax,ds:
                         push si
                         call change_to_dec_init            ; 转换雇员数据
                         popsi
                         adddi,2
                         addsi,40
                         movds:,di                  ; 更新内存中的地址
                         movds:,si                  ; 更新内存中的地址
   ; 录入雇员 end

   ; 录入人均收入 start
                         movdi,ds:                  ; 存入人均收入的偏移地址
                         movsi,ds:                  ; 存入即将要写入数据的偏移地址
                         movax,ds:
                         push si
                         call change_to_dec_init            ; 转换人均收入数据
                         popsi
                         adddi,2
                         addsi,40
                         movds:,di                  ; 更新内存中的地址
                         movds:,si                  ; 更新内存中的地址
   ; 录入人均收入 end

                         popcx
                         deccx
                         jcxz l1_end
                         jmpl1
   l1_end:             nop

                         movcx,21
                         movsi,123H
   ; l3用于输出前的预处理,把每一行后面置为0
   l2:               movbyte ptr ds:,0            ; 每一行最后放0,作为结尾
                         addsi,40
                         loop l2

                         movsi,0FCH                     ; 用于定位字符串数据
                         movdi,0                        ; 用于定位显存位置
                         movdh,3                        ; 行号
                         movdl,30                         ; 列号
                         movbl,2                        ; 颜色
                         call show_str_init
                         movcx,21
   ; l4用于输出数据到显示器
   l3:               push cx
                         call show_str_start
                         adddi,80                         ; 换行.数据占了40列也就是80个字节,所以160-80
                         popcx
                         loop l3

                         movax,4c00h
                         int21h

   ; 名称: change_to_dec
   ; 功能: 将dword或word型数据转变为表示十进制数的字符串,字符串以0结尾
   ; 参数: ax=数据低16位
   ;      dx=数据高16位
   ;      ds:si指向字符串首地址
   ; 返回: 无
   change_to_dec_init: movcx,0
                         push cx                            ; 作为结尾
   change_to_dec_start:movcx,10
                         call divdw
                         addcx,ax                         ; 处理数据中有0意外结束循环的问题
                         jcxz change_to_dec_ok
                         subcx,ax
                         addcx,30h                        ; 算出ASCII码中对应的十进制数
                         push cx                            ; 由于先算出来的是最后一位,先入栈暂存
                         jmpshort change_to_dec_start
   change_to_dec_ok:   popcx
                         jcxz change_to_dec_end
                         movds:,cl
                         incsi
                         jmpshort change_to_dec_ok
   change_to_dec_end:ret

   ; 名称: divdw
   ; 功能:进行不会产生溢出的除法运算
   ; 参数: ax=被除数低16位
   ;      dx=被除数高16位
   ;      cx=除数
   ; 返回: ax=结果低16位
   ;      dx=结果高16位
   ;      cx=余数
   ; 公式:X:被除数、N:除数、H:X高16位、L:X低16位、int():取商、rem():取余数
   ;   X/N=int(H/N)*65536+/N
   divdw:            push ax                            ; 暂存被除数低16位
                         movax,dx                         ; 存放被除数高16位
                         movdx,0                        ; 除数16位的话dx会参与运算,置0避免溢出
                         divcx                            ; 计算int()和rem()
                         movbx,ax                         ; 暂存结果高16位
                         popax
                         divcx                            ; 计算(rem(H/N)*65536+L)/N
                         movcx,dx                         ; 存放返回值余数
                         movdx,bx                         ; 存放返回值高16位
                         ret

   ; 名称: show_str
   ; 功能: 在指定的位置,用指定的颜色,显示一个0结尾的字符串
   ; 参数: dh=行号(取值范围0~24)
   ;      dl=列号(取值范围0~79)
   ;      cl=颜色
   ;      ds:si指向字符串首地址
   ;      ds:di指向当前显示位置
   ; 返回: 无
   show_str_init:      movax,0b800h                     ; 显示区域的开头
                         moves,ax
                         movch,0
                         movcl,dh
   ssil0:            adddi,160                        ; 计算跳到指定行的字节数
                         loop ssil0
                         movcl,dl
   ssil1:            adddi,2                        ; 计算跳到指定列的字节数
                         loop ssil1
                         ret
   show_str_start:   movch,0
                         movcl,ds:
                         jcxz show_str_ok
                         moves:,cl                  ; 存放需要显示的字符
                         moves:,bl                  ; 存放需要显示的颜色
                         incsi
                         adddi,2
                         jmpshort show_str_start
   show_str_ok:      movbyte ptr es:,0            ; 增加一个字符串之间的间隔
                         movbyte ptr es:,0
                         adddi,2
                         incsi                            ; 跳过字符串结尾的‘0’
                         ret
code ends

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