汇编网首页登录博客注册
mxl800的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
  •  编程的最大动力是“终于有个东西听我指挥了”,但事实是电脑也经常和我过不去!!
  • 『姓名』:马兴林              
  • 『性别』:男    『发送消息
  • 个人说明:
  • 详细信息『加为好友』
学习动态
文章收藏
友情链接

[2008-10-29 15:35] 推荐博文 完善的课程设计1!

图片载入中
用了两天的时间,来编程和调试,却被一个非技术性的问题难到了,其实这连错误都不是,就是字符颜色整成黑的了,在黑板上写黑字,还企望能看到什么,估计也就我一个了!呵呵,好在最后在musicvs和jcw2008老师的支持下完成了。
下面炫一下自己的代码,我也去论坛看过了,大家的思路基本都是一样的,但我这个就和大家的完全不一样,代码也比较紧凑,连注释和空行都算上共191行。怎么样,还可以吧?
呵呵,说来炫一下,只是因为程序通过太高兴了,其实并没有自夸的意思,把代码贴出来,可以给后面的人参考一下!以后有时间再把思路整理一下写出来!
下面是代码:
;-----------------------------程序说明-------------------------------;
;名称:ks1                                                           ;
;功能:将data段中的数据在屏幕上按照课设要求显示出来,具体见课程设计1 ;
;思路:将data段中表示年份的21个字符串看作是二维数组,其他数据看作是一;
;      维数组,用bx来做偏移指针,si做字符串的二级指针。              ;
;      开辟一段栈空间用来保护主程序运行现场和程序运行过程的数据暂存。;
;      开辟一段数据段show_buf,用来做显示缓存。                      ;
;------------------------------分割线--------------------------------;

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'
  ;以上是表示21年的21个字符串

  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
  dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
  ;以上是表示21年公司总收入的21个dword型数据

  dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
  dw 11542,14430,15257,17800
  ;以上是表示21年公司雇员人数的21个word型数据
data ends

show_buf segment
  db 80 dup (' ')
show_buf ends

stack segment
  dw 32 dup (0)
stack ends

codesg segment
 start:mov ax,data
       mov ds,ax                ;将data段的段地址存入ds中
       mov ax,show_buf
       mov es,ax                ;将显示缓冲区的段地址存入es中
       mov ax,stack
       mov ss,ax
       mov sp,32
       mov bx,0                 ;用bx作data段的偏移指针(基址)
       mov di,168               ;用di来做总人数的指针
       
       mov dh,1
       mov dl,0                 ;设定显示的初始位置
       mov cx,21                ;设定循环次数
 begin:push cx                  ;保存外层循环计数器
       push dx                  ;保存显示位置
       mov si,0                 ;用si做字符串的二级指针
       mov bp,0                 ;用bp来做显示缓冲区的偏移指针
       mov cx,2                 ;依次将表示年份的字符送入显示缓冲区
  year:mov ax,ds:[bx][si]
       mov es:[bp],ax
       add si,2
       add bp,2
       loop year
       mov ax,ds:[bx+84]        ;将总收入的低16位存入ax中
       mov dx,ds:[bx+86]        ;将总收入的高16位存入dx中
       mov bp,20
       push ax
       push dx
       call dwtoc               ;将总收入转换为字符,并送入显示缓冲区的相应位置
       mov ax,ds:[di]
       mov dx,0
       mov bp,40
       call dwtoc               ;将总人数转换为字符,并送入显示缓冲区的相应位置
       pop dx
       pop ax                   ;还原ax,dx,计算人均收入
       mov cx,ds:[di]           ;用总人数做除数
       call divdw
       mov bp,60
       call dwtoc               ;将人均收入转换为字符,并送入显示缓冲区的相应位置

       mov bp,0                 ;将bp重新指向显示缓冲区的起始位置
       pop dx
       mov cl,2
       call show_str            ;在指定位置显示

       pop cx
       add bx,4                 ;将bx指向下一个年份
       add di,2                 ;将di指向下一个总人数
       inc dh                   ;将显示位置定位到下一行的起始位置
       mov dl,0                                                     
       loop begin

       mov ax,4c00h
       int 21h

;--------------------------数字转为字符的子程序------------------------------;
;名称:dwtoc                                                                 ;
;功能:将dword型数据转换为表示10进制数字的字符串                             ;
;参数:(ax)=要转换数字的低16位,(dx)=要转换数字的高16位                      ;
;      (bp)=在显示缓冲区的存储起始位置                                       ;
;-----------------------------以下是子程序-----------------------------------;
dwtoc:push cx
      push si               ;保护调用程序的运行现场

      mov si,0
 ch_s:mov cx,10             ;开始转换,用除10取余法
      call divdw            ;调用divdw来取得余数
      add cx,30h            ;取得与数字相应的字符
      push cx               ;在栈中暂存
      inc si                ;记录取得的数字个数
      mov cx,ax
      add cx,dx             ;判断商是否为0
      jcxz ch_e             ;是就跳转到标号ch_e处,否就继续运行下面的语句
      jmp short ch_s        ;跳转到标号ch_s处执行程序

 ch_e:mov cx,si             ;转换完成,将结果送入显示缓冲区的相应位置
 buff:pop ax                ;取出字符
      mov es:[bp],al        ;将字符存入显示缓冲区的相应位置
      inc bp
      loop buff

      pop si
      pop cx                ;恢复调用程序的运行现场
      ret                   ;返回调用程序

;--------------------------不会产生溢出的除法子程序------------------------;
;名称:divdw                                                               ;
;功能:进行不会产生溢出的除法运算                                          ;
;参数:(ax)=被除数的低16位,(dx)=被除数的高16位,(cx)=除数                 ;
;返回:(ax)=商的低16位,(dx)=商的高16位,(cx)=余数                        ;
;-------------------------------以下是子程序-------------------------------;
divdw:push bx

      push ax           ;对ax进行暂存
      mov ax,dx         ;将被除数的高16位存入到ax中
      mov dx,0          ;将dx置0
      div cx            ;用除数除以被除数的高16位,商存在ax中,余数存在dx中
      mov bx,ax         ;用bx来暂存商的高16位
      pop ax            ;取出被除数的低16位
      div cx            ;再次进行除法运算,商存在ax中,余数存在dx中
      mov cx,dx
      mov dx,bx         ;根据返回要求进行数据转存

      pop bx
      ret

;---------------------------显示字符串的子程序------------------------------;
;名称:show_str                                                             ;
;功能:将显示缓冲区中的数据显示在显示屏指定的位置,同时将显示缓冲区清空     ;
;参数:(es)=显示缓冲区的段地址,(bp)=显示缓冲区的偏移指针                   ;
;      (dh)=显示位置的行号,(dl)=显示位置的列号                             ;
;      (cl)=显示字符的属性                                                  ;
;------------------------------以下是子程序---------------------------------;
show_str:push ds
         push bx
         push ax
         push di
         push dx
         push si                       ;保护调用程序的运行现场

         mov ax,0b800h
         mov ds,ax                     ;用ds做显示内存的段地址
         mov al,160
         mul dh
         mov bx,ax
         mov al,2
         mul dl
         mov si,ax
                                      ;根据行列号计算显示的具体位置,并将行
                                      ;存入bx中,列存入si中
         push cx                      ;对cx进行暂存
         mov cx,80
  show_s:mov di,cx                    ;保存循环次数
         mov al,es:[bp]
         pop cx
         mov ah,cl
         mov ds:[bx][si],ax
         push cx
         mov cx,di
         mov byte ptr es:[bp],20h
         inc bp
         add si,2
         loop show_s                  ;按要求显示字符

         pop cx
         pop si
         pop dx
         pop di
         pop ax
         pop bx
         pop ds                       ;恢复调用程序的运行现场
         ret


codesg ends
end start
评论次数(7)  |  浏览次数(1936)  |  类型(汇编作业) |  收藏此文  | 

[  游客   发表于  2008-10-29 15:49  ]

恭喜博主,祝更上一层楼!!

[  mxl800   发表于  2008-10-29 16:00  ]

谢谢!谢谢!

[  游客   发表于  2008-10-29 16:10  ]

再次验证,不断努力+坚持=搞定一切!

[  musicvs   发表于  2008-10-29 17:37  ]

哈~恭喜恭喜啊~
那个字符颜色,我还以为你的背景是白色的呢...哈

[  mxl800   发表于  2008-10-30 08:17  ]

呵呵,当初我晕了两天,所有逻辑错误和语法错误都改正了,还是不显示,我说怎么回事呢!jcw2008一说我才明白过来。就是啊,太大意了。

[  lwbfq   发表于  2008-10-30 11:05  ]

博主厉害

[  mxl800   发表于  2008-10-31 15:12  ]

谢谢楼上夸奖,不过我认为这个程序还存在一个问题,当初我为了能够让最后的显示界面清爽一点,用没有显示的地方用空格重新覆盖了一遍,所以这样一来程序运行的时间效率可能要比其他同学的方法低一些。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码