鱼C论坛

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

[汇编作业] 课程设计1

[复制链接]
发表于 2016-11-6 16:13:29 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 bin2yx 于 2016-11-18 22:47 编辑
assume cs:code
data segment
  db '1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995';以上是表示21年的21个字符串,84字节
  dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 ;以上是表示21年公司总收入的21个dword型数据,84字节
  dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226,11542,14430,15257,17800;以上是表示21年公司雇员人数的21个word型数据,42字节
  dw 23 dup (0);拟存入人均收入,多开4个地址备用,地址为252,253,254,255
data ends
stack segment
  db 64 dup (0); 刚开始只设了32个位,后来出现溢出错误,加大到64
stack ends

code segment 
start:mov ax,data
      mov ds,ax
          mov ax,stack
          mov ss,ax
          mov sp,64
          
      call s
          call c
          call e

          mov ax,4c00h
      int 21h        
          
s:    mov bx,84; 公司总收入起始地址    计算人均收入,存入指定内存………………………………………………………………主程序1
          mov si,168; 公司雇员起始地址
          mov di,210; 人均收入起始地址
          mov cx,21
s1:   mov ax,[bx]  ; 这里曾经出现的一个错误,内存中的数据,AX中放不下,应该将高位放在DX中
      mov dx,[bx+2]
          div word ptr [si]
          mov [di],ax
          add bx,4
          add si,2 
          add di,2
          loop s1
          
      mov si,0; 设置原始数据首地址,将ASCII码的数据段,存入指定显存………………………………………………………………主程序2
      mov cx,21
          mov byte ptr ds:[252],1
          mov byte ptr ds:[253],8
          mov byte ptr ds:[254],7
          mov dh,ds:[252]
          mov dl,ds:[253]
          mov bl,ds:[254]
s2:          push cx
          mov cx,4
          mov ax,0
s3:          mov al,[si]
          call show_str
          inc si
          inc dl
          loop s3
          pop cx
          inc dh
          mov ds:[252],dh
          mov dl,ds:[253]
          loop s2
          ret
        
          
c:      ;将dd数据段,转换成ASCII码,存入指定显存        ………………………………………………………………主程序3
        mov si,84
        mov cx,21                
        mov byte ptr ds:[252],1
        mov byte ptr ds:[253],27
        mov byte ptr ds:[254],7
        mov word ptr ds:[255],10
c1:        mov ax,[si];ax=16
        mov dx,[si+2];dx=0
        call cc
        add si,4
        mov al,ds:[252]; 读取并改变显存的行设置,以进行再循环
        inc al 
        mov ds:[252],al        
        loop c1        
    ret 
        
e:    ;将dw数据段,转换成ASCII码,存入指定显存        ………………………………………………………………主程序4,这里设置首地址,循环次数,显存地址、性质、除数
    mov si,168
        mov cx,21
        mov byte ptr ds:[252],1
        mov byte ptr ds:[253],47
        mov byte ptr ds:[254],7
        mov word ptr ds:[255],10
        call e1
        mov si,210
        mov cx,21
        mov byte ptr ds:[252],1
        mov byte ptr ds:[253],67
        mov byte ptr ds:[254],7
        mov word ptr ds:[255],10
    call e1
        ret
        

show_str: push dx;本子程序将ax的数值存放到指定显存,dh=指定行,dl=指定列,bl=指定的显示属性,这里没有push完,调用的话要根据需要添加push
                  push ax
                  mov ax,0b800h
                  mov es,ax
                  mov ax,160
                  mul dh      ;计算所在行的首地址,乘积保存在ax中
                  add dl,dl    ;dl为显示所在的列
                  sub dl,2 
          mov dh,0                  
                  add ax,dx    ;计算出准确目的地的地址,保存在ax中
                  mov bp,ax    ;地址赋值给BX
                  pop ax
                  mov es:[bp],al
                  mov es:[bp+1],bl
                  pop dx
          ret

divdw:push ax; 子程序,进行32位除16位的除法,并杜绝溢出,dx高位,ax低位,di为除数,cx放结果的余数,dx放高位商,ax放低位商,这里没有push完,调用的话要根据需要添加push
          mov ax,dx
          mov dx,0
          div di
          mov si,ax  ;高位除得的商
          pop ax
          div di
          mov cx,dx  ;余数放cx
          mov dx,si         ; 高位除得的商放dx,低位商在ax
          ret
                  
cc: push ax; 子程序,目的是将dd数据和dw数据以10进制显示到频幕,应先设置好原始数据首地址si、需要存放到显存的位置、属性(详见C段)、以及10这个被除数的内存地址
    push bx
        push cx
        push di
        push si
        mov di,ds:[255]
        mov bx,0;  bx很关键,这个是用来记录压入栈的次数的,是用来设置CX的关键!!!!!
c2:        call divdw  ;
    add cx,30h  ; axdx=商  cx=余数+30H
    push cx
        inc bx    ; 这里用来记录压入栈的次数
        mov cx,ax ;假如商(ax)为零,就跳转,不为零继续除
        jcxz c3
        jmp short c2
c3: mov cx,dx
        jcxz c4
        jmp short c2
c4:        ;这里很关键,跳至这里表示所有数据转换完毕,并已压入栈,接下来就是一个一个将他们放入显存
    mov cx,bx
    mov dh,ds:[252] ;dx改成了设置好的行列数
    mov dl,ds:[253]
        mov bl,ds:[254] ;bx改成颜色属性
c5:        pop ax; 显示的设置开始,将第一个数据放入ax待用,因为数据都与余数,肯定只存放在AL
        call show_str
        inc dl 
        loop c5
        pop si
        pop di
        pop cx
        pop bx
        pop ax
        ret           
        
e1:        mov ax,[si]; 子程序,没啥大用
        mov dx,0
        call cc
        add si,2
        mov al,ds:[252]; 读取并改变显存的行设置,以进行再循环
        inc al 
        mov ds:[252],al        
        loop e1
        ret
        
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-25 21:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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