鱼C论坛

 找回密码
 立即注册
查看: 1403|回复: 0

[汇编作业] 课程设计1

[复制链接]
发表于 2023-2-21 17:02:18 | 显示全部楼层 |阅读模式

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

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

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

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

  3. data segment
  4.      ; 21个年头
  5.           db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
  6.           db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
  7.           db '1993','1994','1995'
  8.      ; 21年来每一年的收入,偏移位置开头为54H
  9.           dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  10.           dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  11.      ; 21年来每一年的雇员,偏移位置开头为A8H
  12.           dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  13.           dw 11542,14430,15257,17800
  14.      ; 存放每一年的人均收入,偏移地址开头为D2H
  15.           dw 21 dup (0)
  16.      ; 21行40列的输出字符串,偏移地址开头为FCH
  17.           db 840 dup (20H)
  18.      ;  偏移地址开头为444H,分别是年份、收入、雇员、人均收入的偏移地址
  19.           dw 0H,54H,0A8H,0D2H
  20.      ;  偏移地址开头为44cH,分别是年份、收入、雇员、人均收入字符串的偏移地址
  21.           dw 0FCH,106H,110H,11AH
  22. data ends

  23. stack segment
  24.            dw 8 dup (0)
  25. stack ends

  26. code segment
  27.      start:              mov  ax,data
  28.                          mov  ds,ax
  29.                          mov  ax,stack
  30.                          mov  ss,ax
  31.                          mov  sp,32

  32.                          mov  si,54H                        ; 用于定位年收入
  33.                          mov  di,0A8H                       ; 用于定位年雇员
  34.                          mov  bp,0D2H                       ; 用于定位人均收入
  35.                          mov  cx,21
  36.      ; l0用于计算年人均收入
  37.      l0:                 mov  ax,ds:[si]
  38.                          mov  dx,ds:[si+2]
  39.                          mov  bx,ds:[di]
  40.                          div  bx                            ; 计算年人均收入
  41.                          mov  ds:[bp],ax                    ; 存入计算得出的人均收入
  42.                          add  si,4
  43.                          add  di,2
  44.                          add  bp,2
  45.                          loop l0

  46.                          mov  cx,21
  47.      l1:                 push cx
  48.      ; 存入年份 start
  49.                          mov  di,ds:[444H]                  ; 存入即将要处理的年份的偏移地址
  50.                          mov  si,ds:[44CH]                  ; 存入即将要写入数据的偏移地址
  51.                          mov  ax,ds:[di]                    ; 存入即将要处理的年份
  52.                          mov  ds:[si],ax                    ; 将年份存入字符串
  53.                          mov  ax,ds:[di+2]                  ; 存入即将要处理的年份
  54.                          mov  ds:[si+2],ax                  ; 将年份存入字符串
  55.                          add  di,4                          ; 移到下一个要处理的年份
  56.                          add  si,40                         ; 移到下一行,对应年份的位置
  57.                          mov  ds:[444H],di                  ; 更新内存中的地址
  58.                          mov  ds:[44CH],si                  ; 更新内存中的地址
  59.      ; 存入年份 end

  60.      ; 存入收入 start
  61.                          mov  di,ds:[446H]                  ; 存入即将要处理的收入的偏移地址
  62.                          mov  si,ds:[44EH]                  ; 存入即将要写入数据的偏移地址
  63.                          mov  ax,ds:[di]
  64.                          mov  dx,ds:[di+2]
  65.                          push si
  66.                          call change_to_dec_init            ; 转换收入数据
  67.                          pop  si
  68.                          add  di,4
  69.                          add  si,40
  70.                          mov  ds:[446H],di                  ; 更新内存中的地址
  71.                          mov  ds:[44EH],si                  ; 更新内存中的地址
  72.                          mov  dx,0
  73.      ; 存入收入 end

  74.      ; 录入雇员 start
  75.                          mov  di,ds:[448H]
  76.                          mov  si,ds:[450H]                  ; 存入即将要写入数据的偏移地址
  77.                          mov  ax,ds:[di]
  78.                          push si
  79.                          call change_to_dec_init            ; 转换雇员数据
  80.                          pop  si
  81.                          add  di,2
  82.                          add  si,40
  83.                          mov  ds:[448H],di                  ; 更新内存中的地址
  84.                          mov  ds:[450H],si                  ; 更新内存中的地址
  85.      ; 录入雇员 end

  86.      ; 录入人均收入 start
  87.                          mov  di,ds:[44AH]                  ; 存入人均收入的偏移地址
  88.                          mov  si,ds:[452H]                  ; 存入即将要写入数据的偏移地址
  89.                          mov  ax,ds:[di]
  90.                          push si
  91.                          call change_to_dec_init            ; 转换人均收入数据
  92.                          pop  si
  93.                          add  di,2
  94.                          add  si,40
  95.                          mov  ds:[44AH],di                  ; 更新内存中的地址
  96.                          mov  ds:[452H],si                  ; 更新内存中的地址
  97.      ; 录入人均收入 end

  98.                          pop  cx
  99.                          dec  cx
  100.                          jcxz l1_end
  101.                          jmp  l1
  102.      l1_end:             nop

  103.                          mov  cx,21
  104.                          mov  si,123H
  105.      ; l3用于输出前的预处理,把每一行后面置为0
  106.      l2:                 mov  byte ptr ds:[si],0            ; 每一行最后放0,作为结尾
  107.                          add  si,40
  108.                          loop l2

  109.                          mov  si,0FCH                       ; 用于定位字符串数据
  110.                          mov  di,0                          ; 用于定位显存位置
  111.                          mov  dh,3                          ; 行号
  112.                          mov  dl,30                         ; 列号
  113.                          mov  bl,2                          ; 颜色
  114.                          call show_str_init
  115.                          mov  cx,21
  116.      ; l4用于输出数据到显示器
  117.      l3:                 push cx
  118.                          call show_str_start
  119.                          add  di,80                         ; 换行.数据占了40列也就是80个字节,所以160-80
  120.                          pop  cx
  121.                          loop l3

  122.                          mov  ax,4c00h
  123.                          int  21h

  124.      ; 名称: change_to_dec
  125.      ; 功能: 将dword或word型数据转变为表示十进制数的字符串,字符串以0结尾
  126.      ; 参数: ax=数据低16位
  127.      ;      dx=数据高16位
  128.      ;      ds:si指向字符串首地址
  129.      ; 返回: 无
  130.      change_to_dec_init: mov  cx,0
  131.                          push cx                            ; 作为结尾
  132.      change_to_dec_start:mov  cx,10
  133.                          call divdw
  134.                          add  cx,ax                         ; 处理数据中有0意外结束循环的问题
  135.                          jcxz change_to_dec_ok
  136.                          sub  cx,ax
  137.                          add  cx,30h                        ; 算出ASCII码中对应的十进制数
  138.                          push cx                            ; 由于先算出来的是最后一位,先入栈暂存
  139.                          jmp  short change_to_dec_start
  140.      change_to_dec_ok:   pop  cx
  141.                          jcxz change_to_dec_end
  142.                          mov  ds:[si],cl
  143.                          inc  si
  144.                          jmp  short change_to_dec_ok
  145.      change_to_dec_end:  ret

  146.      ; 名称: divdw
  147.      ; 功能:进行不会产生溢出的除法运算
  148.      ; 参数: ax=被除数低16位
  149.      ;      dx=被除数高16位
  150.      ;      cx=除数
  151.      ; 返回: ax=结果低16位
  152.      ;      dx=结果高16位
  153.      ;      cx=余数
  154.      ; 公式:X:被除数、N:除数、H:X高16位、L:X低16位、int():取商、rem():取余数
  155.      ;     X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N
  156.      divdw:              push ax                            ; 暂存被除数低16位
  157.                          mov  ax,dx                         ; 存放被除数高16位
  158.                          mov  dx,0                          ; 除数16位的话dx会参与运算,置0避免溢出
  159.                          div  cx                            ; 计算int()和rem()
  160.                          mov  bx,ax                         ; 暂存结果高16位
  161.                          pop  ax
  162.                          div  cx                            ; 计算(rem(H/N)*65536+L)/N
  163.                          mov  cx,dx                         ; 存放返回值余数
  164.                          mov  dx,bx                         ; 存放返回值高16位
  165.                          ret

  166.      ; 名称: show_str
  167.      ; 功能: 在指定的位置,用指定的颜色,显示一个0结尾的字符串
  168.      ; 参数: dh=行号(取值范围0~24)
  169.      ;      dl=列号(取值范围0~79)
  170.      ;      cl=颜色
  171.      ;      ds:si指向字符串首地址
  172.      ;      ds:di指向当前显示位置
  173.      ; 返回: 无
  174.      show_str_init:      mov  ax,0b800h                     ; 显示区域的开头
  175.                          mov  es,ax
  176.                          mov  ch,0
  177.                          mov  cl,dh
  178.      ssil0:              add  di,160                        ; 计算跳到指定行的字节数
  179.                          loop ssil0
  180.                          mov  cl,dl
  181.      ssil1:              add  di,2                          ; 计算跳到指定列的字节数
  182.                          loop ssil1
  183.                          ret
  184.      show_str_start:     mov  ch,0
  185.                          mov  cl,ds:[si]
  186.                          jcxz show_str_ok
  187.                          mov  es:[di],cl                    ; 存放需要显示的字符
  188.                          mov  es:[di+1],bl                  ; 存放需要显示的颜色
  189.                          inc  si
  190.                          add  di,2
  191.                          jmp  short show_str_start
  192.      show_str_ok:        mov  byte ptr es:[di],0            ; 增加一个字符串之间的间隔
  193.                          mov  byte ptr es:[di+1],0
  194.                          add  di,2
  195.                          inc  si                            ; 跳过字符串结尾的‘0’
  196.                          ret
  197. code ends

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-19 04:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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