***汇编语言 课程设计1 格式化输出公司数据

汇编语言 课程设计1 格式化输出公司数据

子程序描述

名称:dtoc
功能:将dword型数据转变为表示十进制数的字符串,字符串以0位结尾符
参数:
    (ax)=dword型数据的低16位
    (dx)=dword型数据的高16位
    ds:si指向字符串的首地址
返回:无 

程序

assume cs:code

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 

code segment
start:
    mov ax,data
    mov ds,ax
    mov bx,0
    mov ax,0b800h
    mov es,ax
    mov di,0

    mov cx,25*160
clean:  mov byte ptr es:[di],0
    inc di
    loop clean

outer:
    call year
    call interest
    call employee
    call salary

    mov ax,4c00h
    int 21h
;写入年份
year:
    mov bp,640;从第五行(160*4)开始,因为前面几行会被刷新掉
    mov cx,21
next_year:
    push cx
    mov cx,4
s1: 
    mov ah,02
    mov al,ds:[bx]
    mov es:[bp],ax
    add bp,2
    inc bx
    loop s1
    ;完成了一行的年输入,下面进行剩下的年输入
    add bp,152;(160-8)
    pop cx
    loop next_year
    ret
;结束写入年份
;写入收入
interest:
    mov bp,480;(540-160),因为第一次的时候不需要下面的add bp,160所以在这里先将其减去
    mov cx,21
next_interest:
    push cx
    mov di,16;在每行上的偏移地址
    add bp,160;到下一行
    mov si,0;记录入栈次数
    ;下面将收入先入栈后出栈
    mov ax,ds:[bx]
    add bx,2
    mov dx,ds:[bx]
s2: mov cx,10
    call divdw
    add cl,30h
    mov ch,2;
    push cx
    inc si
    ;下面检测得出的商是否等于0
    ;由于商有可能占四个字节,所以必须分别判断高位和低位是否等于0
    mov cx,dx
    jcxz high0
    ;高位不是0,直接进行下一次数据入栈循环
    jmp s2
high0:  mov cx,ax
    jcxz reverse2;全是0,直接开始数据出栈
    ;高位是0,低位不是
    jmp s2
reverse2:
    mov cx,si
s3:
    pop dx
    mov es:[bp][di],dx
    add di,2
    loop s3
    pop cx
    add bx,2
    loop next_interest

    ret
;结束写入收入

;32位被除数div
;输入:ax 低16,dx 高16, cx 除数
;输出:ax 低16,dx 高16, cx 余数
divdw:;此时应该已经完成了输入操作
    push bx
    push ax
    mov ax,dx
    mov dx,0
    div cx
    mov bx,ax
    pop ax
    div cx
    mov cx,dx
    mov dx,bx
    pop bx

    ret


;写入雇员数
employee:
    mov bp,640
    mov di,40
    mov cx,21
next_employee:
    call dtoc_em
    ret
;结束写入雇员数

;写入人均收入
salary:
    mov bp,640
    mov di,64
    mov cx,21
    mov bx,84
    mov si,168
next_salary:
    push cx
    mov ax,ds:[bx];读入公司收入
    add bx,2
    mov dx,ds:[bx]
    mov cx,ds:[si]
    push bx
    push si
    mov si,0
    call divdw
    ;ax存放的是应该显示的数,但是占了16位。要想显示出来必须将其分为两个八位数
show:
    mov dx,0
    mov cx,10
    call divdw
    mov ch,2
    add cl,30h
    push cx
    inc si;用于记录入栈的次数
    mov cx,ax
    inc cx
    loop show;如果商是0则停止入栈
    mov cx,si
reverse3:
    pop dx
    mov es:[bp][di],dx
    add di,2
    loop reverse3
    pop si
    pop bx
    pop cx
    add si,2
    add bx,2
    add bp,160
    mov di,64
    loop next_salary

    ret

;结束写入人均收入

dtoc_em:;未保存现场
    push cx
    mov ax,ds:[bx]
    mov dx,0
    push si
    mov si,0
dtoc_word:
    mov cx,10
    div cx
    mov dh,2
    add dl,30h
    push dx
    mov dx,0
    inc si
    mov cx,ax
    inc cx
    loop dtoc_word;如果商(ax)为0则退出入栈循环
reverse_w:;将栈中的个位数出栈,放在显存中
    mov cx,si
proc3:  
    pop dx
    mov es:[bp][di],dx
    add di,2
    loop proc3
    mov di,40
    add bp,160
    pop si
    pop cx
    add bx,2;供读取下一个word型数据
    loop dtoc_em
    ret

code ends
end start

写给自己的一些题外话:这个程序做了很久很久。。断断续续大概四五天的样子,不知不觉对汇编语言有了一点抵触,可能因为题目的难度渐渐增加了吧。不过还好,最终还是做出来了。之前一直害怕各种莫名其妙的小bug,现在发现,再小的bug都不是凭空产生的,都是源于考虑不周到,对程序的不熟悉 ————–2017-5-28 22:39:22

原文地址:https://www.cnblogs.com/litlife/p/7512772.html