kane080824 发表于 2011-11-17 17:44:16

菜鸟刚出炉的课程设计1,热腾腾滴~~

本帖最后由 kane080824 于 2011-11-21 20:57 编辑



http://bbs.fishc.com/data/attachment/album/201111/17/1403418uum8jppjh3o8n37.jpg
程序运行截图
assume cs:code,ds:data,ss:varreg
datasegment
db '1975','1976','1977','1978','1979','1980','1981',
    '1982','1983','1984','1985','1986','1987','1988',
    '1989','1990','1991','1992','1993','1994','1995'                ;年份(内存起始地址:0)
   
dd 16,22,382,1356,2390,8000,16000,24486,
50065,97479,140417,197514,345980,590827,803530,
1183000,1843000,2759000,3753000,4649000,5937000   ;公司收入数据(内存起始地址:84)
   
dd 3,7,9,13,28,38,130,220,476,778,1001,1442,
2258,2793,4037,5635,8226,11542,14430,15257,17800    ;公司人员数(内存起始地址:168)

dd 21 dup(0)                            ;公司人均收入(内存起始地址:252)

dw 10                                     ;分离字符所用的除数(内存起始地址:336)

db 16 dup(0)                            ;ascii码暂存区(内存起始地址:338)
dataends
varregsegment
dw 32 dup(0)                            ;栈,用于保存参数进行主\子程序间传递
varregends   
code   segment                         ;程序流程是处理一个数据显示一个数据,逐行显示
   start:   mov ax,data
                  mov ds,ax             ;数据段
                  mov ax,varreg
                  mov ss,ax                ;栈段
                  mov sp,32
                                                 ;外循环入口
                  mov si,0                  ;年份\收入\员工三项数据指针
                  mov bp,0                ;显示换行指针
                  mov cx,21                ;开始进行数据处理
                     
          s0:push cx                   ;保存外循环(行循环)次数
               mov ax,0b800h         
               mov es,ax                ;显存段地址复位
               mov ax,84            ;取收入低16位
               mov dx,84       ;取收入高16位
               div word ptr 168 ;取员工数并计算人均收入
               mov252,ax      ;将人均收入写入数据
   
                push       
                push
                popds:338
                popds:338       ;将年份数据写入ascii码保存区
      
                                             ;内循环入口
      movbx,0                         ;内循环不同数据间读取指针
      movcx,4                         ;内循环,每一轮循环处理一行四种数据,处理一个显示一个
      push cx
      jmpscrn                        ;年份无需转换ascii码可直接显示
      
   s:pushcx                         ;保存内循环(列循环)次数   
                call str_ascii          ;调用ascii码转换子程序
   scrn:call show_str          ;调用显示字符串子程序
   addbx,84
      movax,es
      incax                              ;通过循环改变显示段地址达到逐列显示
      moves,ax      
      popcx
      loops                               ;内循环出口
      
      addsi,4
      addbp,160
      popcx
      loops0                            ;外循环出口
      movax,4c00h
      int21h                            ;主程序结束
   
str_ascii:                            ;ascii码转换子程序
         mov ax,
         mov dx,       ;取数据作为被除数
         movcx,0         
         push cx                      ;ascii串在栈中的结束标记
                                                         
                                           ;以下是X/N无溢出除法算法,使用公式                                    
                                           ;X/N=int(H/N)*65536+/N      
      M:mov cx, ax            ;保存被除数低16位L至cx
      mov ax, dx                   ;将被除数高16位H作被除数
      mov dx, 0
      div word ptr ds:    ;H/N,N为10
      push ax                        ;保存H/N的商
      mov ax, cx                     ;把低16位和dx组成
      div word ptr ds:   ;/N
      mov cx, dx                  ;将余数给cx,即X/N的余数
      pop dx                         ;此时的dx,ax即为X/N的商   
      
         add cx, 30h         ;把过滤出的余数转成ascii码值
         pushcx                ;ascii码值入栈
      
          mov cx, ax          ;开始校验被除数是否为0
          jcxzH                ;判断被除数低16位是否为0
          jmp   M                ;如果被除数不为0,继续除余
   H:mov cx,dx
         mov di,0                ;ascii码内存区指针
         jcxzR                   ;判断被除数高16位是否为0
         jmp M               
                                       ;以下ascii码值出栈
   R:pop cx                  ;将栈中的ascii值逐个弹出
         jcxzRE                  ;如果为0,表明弹完回到主程序
         mov 338,cl      ;将ascii码值写入ascii保存区
         incdi
         jmp   R
RE: ret   
      
show_str:   mov di,0                   ;显示字符串子程序
      TAKE:   mov cl,338      
                      mov ch,0
                      jcxzGB
                      mov al,0
                      mov 338,al             ;复位ascii码内存区
                      mov ch,2
                      push di
                      add di,di
                      mov es:326,cx    ;将ascii值写入显示区,326是根据行列得出的偏移量
                     pop di
                     inc di   
                     jmp   TAKE
          GB:ret   
codeends
       endstart                   


wuge1986 发表于 2011-11-18 12:47:18

看不懂啊,这个不是会汇编写的吧!

kane080824 发表于 2011-11-18 14:22:17

呵呵,不是汇编是什么,其实程序流程很简单,以第一次循环为例:把1975读入ascii码保存区(因为年份本已经是字符故无需转换ascii码),然后调用显示子程序进行显示,接着把第一行的第二列数据收入16读入,因为它只是个十进制数,所以调用ascii转换子程序,转换后写入ascii保存区,然后显示,依次类推,处理一个显示一个,一行四个数据为一个内循环,外循环有21个,每一轮外循环里包含四个内循环,即一个外循环处理一行,21次循环处理完毕所有数据

yulin3192 发表于 2011-11-20 15:03:27

郁闷了
现在没有学习的动力了

kane080824 发表于 2011-11-21 21:13:20

{:5_110:}上面兄弟撑住啦~~,我学了3个多星期了,有时候也是觉得很难,一个问题一想就是几个小时而且还没结果,痛苦得很失望灰心,在做显示"welcome to masm!"这个实验时,我一天一夜都没睡,只是不甘心,等成功的了,我是多么高兴,希望你别放弃,大家一起学多个伴吧

wx2528525876 发表于 2011-12-2 15:54:53

不错不错。。

飘飞的夏秋 发表于 2012-8-6 10:55:20

好玩,果断支持
页: [1]
查看完整版本: 菜鸟刚出炉的课程设计1,热腾腾滴~~