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

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
最新评论
最新留言
好友圈
友情链接

[2020-07-28 18:42] 课程设计1

assume cs:code,ds:data

data segment
db '1975','1976','1977','1978','1979','1980','1981'
db '1982','1983','1984','1985','1986','1987','1988'
db '1989','1990','1991','1992','1993','1994','1995',0

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514,345980
dd 590827,803530,1183000,1843000,2759000,3753000,4649000,5937000,0

dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793
dw 4037,5635,8826,11542,14430,15257,17800,0

dw 5,3,42,104,85,210,123,111,105,125,140,136,153,211,199,209,224,239,260,304,333,0
data ends

code segment
start:
mov ax,data
mov ds,ax

mov ax,0b800h
mov es,ax

call show_year    ;输出年份
call show_output;输出收入
call show_num   ;输出雇员数
call show_input  ;人均收入
mov ax,4c00h
int 21h
;1111111111111111111111---------------------------------------
show_year:push ax
                 push bx
                 push cx
                 push dx
                 push es
                 push si
                 push di
                 push bp

                 mov al,0a0h
                 mov bl,02h
                 mul bl
                 mov bx,ax                             ;bx存储行偏移量,年份处第3行
                 mov si,0                                ;data段的内容从0开始取数据

show:        mov ch,0
                 mov cl,[si]                              ;cx内为字符或为字符最后的0
                 inc si                                     ;si代表data内的字符位置,在打印过程中不应当清零,每次增一字节,第一次存字符,第二次存属性
                 jcxz ok                                  ;若cx不为0则顺序执行,为0则跳转到ok标记
;这里可以用个4次的循环,目前就算了
                 mov es:[bx],cl
                 mov byte ptr es:1[bx],02h      ;第1个字
                 mov cl,[si]
                 inc si
                 mov es:2[bx],cl
                 mov byte ptr es:3[bx],02h      ;第2个字
                 mov cl,[si]
                 inc si
                 mov es:4[bx],cl
                 mov byte ptr es:5[bx],02h      ;第3个字
                 mov cl,[si]
                 inc si
                 mov es:6[bx],cl
                 mov byte ptr es:7[bx],02h        ;第4个字
                 add bx,0a0h
                 jmp short show                     ;打下一个年份
ok:            pop bp
                 pop di
                 pop si
                 pop es
                 pop dx
                 pop cx
                 pop bx
                 pop ax
                 ret                     ;当cl从[si]取得0时就代表字符串打完了
;1111111111111111111111111111111111111111111111111111111----------------------------------------------------------------------------------------------------------------
;2222222222222222222222222222222222222222222222222222222-----------------------------------------------------------------------------------------
show_output:push ax         ;这个子程序只是调用,要保存子程序中用到的相关寄存器的值
                     push bx
                     push cx
                     push si
                     push bp
                     push dx
                     push di

                     mov ax,00a0h
                     mov bl,02h                         ;减一位预设行,用于下边循环递增
                     mul bl
                     mov bx,ax                           ;bx存储行偏移量,收入处第3行
                     mov bp,0                            ;全局只清零一次
;这个si的定位必须的,有可能是上边哪里出问题了
                     mov si,55h
;此处的bx内容在整个计算/转换过程中都不能修改,否则显示不出来

fetch:             mov ax,[si]                   ;上一个call已经把si指向收入的第一个数据了,但由于是dd型,于是低位在前并放入ax
                     add si,02h
                     mov dx,[si]                   ;高位在后并放入dx
                     add si,02h
                     mov cx,ax                    ;ax低位检测是否为0
                     jcxz cmbk                    ;取到数据段中的0即代表收入数据个数够了,跳出该子程序
;此时ax、bx、cx、dx、bp已经被初始化,下方修改cx故cx是什么无所谓,bp应当为0,dx和ax组成被除数,bx为行数
;以下为没取完数据的流程

trsfm:            mov cx,10
                     call divdw
;此时dx内装余数,ax内装商,divdw函数中余数位于cx
                     add cx,30h
                     push cx                     ;余数加30h之后为相应余数的ascii码,入栈用于顺序输出
                     mov cx,ax
                     inc bp
                     jcxz prnt            ;ax=cx=0则开始打印该十进制数(实际上是字符串)

;cx不为零即需要继续除10来取得余数,先假设ax内的商没有溢出
                     jmp short trsfm

prnt:              mov cx,bp         ;得到pop次数
                     mov bp,0
                     mov di,10                 ;di存储列偏移量,收入处第6列,其中第五列放空先不管
print:             pop ax
                     mov es:[bx+di],al
                     inc di
                     mov byte ptr es:[bx+di],02h
                     inc di
loop print

                     add bx,00a0h
                     jmp short fetch              ;重新取数据
cmbk:            pop di
                     pop dx
                     pop bp
                     pop si
                     pop cx
                     pop bx
                     pop ax
ret

;双字型数据的除法子函数(防溢出)---------------------------------------------------------------------------------------------
divdw:
;ax装低16位,dx装高16位,cx装除数,bx绝对不能动,结果dx返回高16位,ax返回低16位
;计算(dx)/(cx)
                     push bx
                     push ax
;先算高16位
                     mov ax,dx
                     mov dx,0
                     div cx                   ;(ax)即结果的高16位,余数(dx)就是下一回div时被除数的高16位
                     mov bx,ax            ;bx内为本次除法结果的高16位
;下面计算原本的被除数的低16位
                     pop ax
                     div cx                  ;(ax)即结果的低16位本位,本次被除数的余数在dx中
                     mov cx,dx
                     mov dx,bx
;还原bx内容
                     pop bx
ret
;222222222222222222222222222222222222222222222------------------------------------------------------
;333333333333333333333333333333333333333333333------------------------------------------------------
show_num:push ax         ;这个子程序只是调用,要保存子程序中用到的相关寄存器的值
                  push bx
                  push cx
                  push si
                  push bp
                  push dx
                  push di

                  mov ax,00a0h
                  mov bl,02h
                  mul bl
                  mov bx,ax                           ;bx存储行偏移量,从第三行开始
                  mov bp,0                            ;全局只清零一次
;这个si的定位必须的,上边的si已经退出了,被pop处新的数了
                  mov si,0adh
;此处的bx内容在整个计算/转换过程中都不能修改,否则显示不出来

fetch1:        mov ax,[si]                   ;数据取入ax内,此次dw数据大小不超过16位
                  add si,02h
                  mov dx,0                     ;dx得清零
                  mov cx,ax                    ;ax位检测是否为0
                  jcxz change                 ;取到数据段中的0即代表收入数据个数够了,跳出该子程序
;此时ax、bx、cx、dx、bp已经被初始化,下方修改cx故cx是什么无所谓,bp应当为0,dx和ax组成被除数,bx为行数
;以下为没取完数据的流程

trsfm1:        mov cx,10
                  div cx
;此时ah内装余数,al内装商
                  add dx,30h
                  push dx                     ;余数加30h之后为相应余数的ascii码,入栈用于顺序输出
;此处有个问题就是dx没有清零的话,就会出现dx为前一次除法的余数+30h,所以可能表现为除法溢出,使得下次div溢出然后add dx,30h变成???
                  mov dx,0                  
                  mov cl,al
                  inc bp
                  jcxz prnt1                   ;al=cl=0则开始打印该十进制数(实际上是字符串)
                  jmp short trsfm1

prnt1:         mov cx,bp                  ;得到pop次数
                  mov bp,0
                  mov di,1ah                 ;di存储列偏移量,雇员数处第14列,其中第13列放空先不管
print1:        pop ax
                  mov es:[bx+di],al
                  inc di
                  mov byte ptr es:[bx+di],02h
                  inc di
loop print1

                  add bx,00a0h
                  jmp short fetch1              ;重新取数据
change:      pop di
                  pop dx
                  pop bp
                  pop si
                  pop cx
                  pop bx
                  pop ax
ret
;33333333333333333333333333333333333333333-------------------------------------------
;44444444444444444444444444444444444444444-------------------------------------------
show_input:push ax         ;这个子程序只是调用,要保存子程序中用到的相关寄存器的值
                  push bx
                  push cx
                  push si
                  push bp
                  push dx
                  push di

                  mov ax,00a0h
                  mov bl,02h
                  mul bl
                  mov bx,ax                           ;bx存储行偏移量,从第三行开始
                  mov bp,0                            ;全局只清零一次
;这个si的定位必须的,上边的si已经退出了,被pop处新的数了
                  mov si,0d9h
;此处的bx内容在整个计算/转换过程中都不能修改,否则显示不出来

fetch2:        mov ax,[si]                   ;数据取入ax内,此次dw数据大小不超过16位
                  add si,02h
                  mov dx,0                     ;dx得清零
                  mov cx,ax                    ;ax位检测是否为0
                  jcxz change1                 ;取到数据段中的0即代表收入数据个数够了,跳出该子程序
;此时ax、bx、cx、dx、bp已经被初始化,下方修改cx故cx是什么无所谓,bp应当为0,dx和ax组成被除数,bx为行数
;以下为没取完数据的流程

trsfm2:        mov cx,10
                  div cx
;此时ah内装余数,al内装商
                  add dx,30h
                  push dx                     ;余数加30h之后为相应余数的ascii码,入栈用于顺序输出
;此处有个问题就是dx没有清零的话,就会出现dx为前一次除法的余数+30h,所以可能表现为除法溢出,使得下次div溢出然后add dx,30h变成???
                  mov dx,0                  
                  mov cl,al
                  inc bp
                  jcxz prnt2                   ;al=cl=0则开始打印该十进制数(实际上是字符串)
                  jmp short trsfm2

prnt2:         mov cx,bp                  ;得到pop次数
                  mov bp,0
                  mov di,26h                 ;di存储列偏移量,雇员数处第14列,其中第13列放空先不管
print2:        pop ax
                  mov es:[bx+di],al
                  inc di
                  mov byte ptr es:[bx+di],02h
                  inc di
loop print2

                  add bx,00a0h
                  jmp short fetch2              ;重新取数据
change1:    pop di
                  pop dx
                  pop bp
                  pop si
                  pop cx
                  pop bx
                  pop ax
ret
;------------------------------------------------------------------
code ends
end start





容我吐槽一句,我要设计哭了
评论次数(0)  |  浏览次数(392)  |  类型(默认类型) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码