鱼C论坛

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

[汇编作业] 课程设计1

[复制链接]
发表于 2020-3-17 22:05:26 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 雪球丶 于 2020-3-17 23:56 编辑
assume cs:code,ss:stack

data segment 
        ;data
        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年的字符串
        
        ;data + 54H (84)
        dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
        dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
        ;21个年份公司的总收入
        
        ;data + A8H(168)
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
        dw 11542,14430,15257,17800
        ;21个年份的雇员数
data ends

table segment
        ;                        年份 收入 雇员 人均收入
        db 21 dup ('year summ ne ?? ')
table ends

;创建一个数据段,用来存放格式化之后的数据,用空格填充
;每行 年份起始索引0,收入起始索引20,雇员数起始索引40,人均收入起始索引60
format segment
        db 1680 dup (' ')
        db 0
format ends

stack segment
        db 128 dup(0)
stack ends

;将12666以十进制的形式在屏幕的8行3列用绿色显示出来
code segment
start:
                mov ax,stack
                mov ss,ax
                mov sp,128
                
                mov ax,data
                mov ds,ax                        ;初始化数据段
                mov ax,table
                mov es,ax                        ;es指向table段地址
                
                ;es指向table段地址
                call dneat ;整理数据
                
                
                ;将数据中的数字转换为ascii
                mov ax,table
                mov es,ax                ;table段
                mov ax,format
                mov ds,ax                ;format段        
                mov bx,0                ;table行索引
                mov si,0                ;format行索引
                
                mov cx,21
        ts: 
                ;拷贝年份数据-字符串(四字节)
                mov ax,es:[bx]
                mov ds:[si],ax
                mov ax,es:[bx+2h]
                mov ds:[si+2h],ax
                
                ;将收入转换为ascii的数字(四字节)
                mov ax,es:[bx+5h]        ;收入低16位
                mov dx,es:[bx+7h]        ;收入高16位
                push bx
                push cx
                push si
                add si,20                        ;写到format段每行的第20列处
                ;函数 dtoc
                ;将word(16位)型数据转变位标识十进制数的字符串,字符串以0结尾,存放在ds处
                ;输入参数:
                ;                (ax) = 32位数字的第16位
                ;                (dx) = 32位数字的高16位
                ;                ds:si指向字符串首地址
                ;返回值: 无
                call dtoc
                ;最后一位多多加了一个0,把0去掉,改为空格
                mov al,20H
                mov ds:[di],al
                pop si
                pop cx
                pop bx 
                
        
                ;将雇员数改为ascii的数字(2字节)
                mov ax,es:[bx+0ah]
                mov dx,0000h
                push bx
                push cx
                push si
                add si,40                        ;写到format段每行的第40列处
                call dtoc
                ;最后一位多多加了一个0,把0去掉,改为空格
                mov al,20H
                mov ds:[di],al
                pop si
                pop cx
                pop bx 
                
                ;将平均工资改为ascii的数字(2字节)
                mov ax,es:[bx+0dh]
                mov dx,0000h
                push bx
                push cx
                push si
                add si,60                        ;写到format段每行的第60列处
                call dtoc
                ;最后一位多多加了一个0,把0去掉,改为空格
                mov al,20H
                mov ds:[di],al
                pop si
                pop cx
                pop bx 
                
                add si,80
                add bx,16
                loop ts

                ;将format段的第22行第一个数据(21x80 + 1= 1681)改为0,作为输出结束标识
                mov ax,0
                mov ds:[1681],ax
                
                ;显示
                mov dh,1        ;第1行
                mov dl,0        ;第0列
                mov cl,2        ;颜色
                mov ax,format
                mov ds,ax
                mov si,0
                call show_str
                
                mov ax,4C00H
                int 21H


;将word(16位)型数据转变位标识十进制数的字符串,字符串以0结尾,存放在ds处
;输入参数:
;                (ax)=word型数据
;                ds:si指向字符串首地址
;返回值: 无
;32位除法所需的寄存器:DX被除数的高16位,AX被除数的低16位,reg,除数(这里是cx)结果:AX商,DX余数
dtoc:        ;mov dx,0000H
                mov di,si
                mov bx,0        ;字符长度计数
                ;输入参数:
                ;        (ax)=dword型数据的低16位
                ;        (dx)=dowrd型数据的高16位
                ;        (cx)=除数
                ;返回值:
                ;        (dx)=结果的高16位,(ax)=结果的低16位
                ;        (cx)=余数
        s0:        mov cx,0AH
                push bx                                ;divdw函数内部会改变bx的值,把bx暂存起来
                push si
                call divdw        
                pop si
                pop bx
                push cx                                ;数据入栈,因为算出来的顺序是反的,所以用栈来倒一下
                inc bx
                ;检查商是否为0,为0则计算结束,跳出循环
                push ax                                ;ax寄存器的值后面还有用,先保存起来
                or ax,dx
                mov cx,ax
                pop ax
                jcxz s1 
                inc di
                mov cx,2
                loop s0
        s1:        
                mov di,si
                mov cx,bx
        ens:
                pop ax
                add ax,30H                        ;转换为ASCII
                mov ds:[di],al
                inc di
                loop ens
                mov cl,0                        ;末尾写入0
                mov ds:[di],cl
                ret
                
show_str:
                mov ax,0b800H        ;显存地址
                mov es,ax
                ;计算像素点索引 = rowx160 + colx2
                add dl,dl
                mov al,dh
                mov bl,160
                mul bl                        ;计算出来的行号存储在ax中
                
                mov dh,0
                add ax,dx                
                mov di,ax                ;像素写索引
                mov dh,cl                ;先用dl记录下颜色值,后面直接用dx寄存器写显存;CX寄存器在循环中会被用到,释放cl
        ws:                                        ;写显存
                mov dl,ds:[si]
                mov es:[di],dx
                inc si
                add di,2
                ;查看下一位是否为0
                mov cx,0
                mov cl,ds:[si]
                jcxz wd                        ;若下一位为0,则跳转到wd处
                mov cx,2                ;给CX赋值,如果程序走到这里说明下一位不为0就让其不断循环继续往下写
                loop ws
        wd:        ret

divdw:
                mov si,ax        ;低16位暂存在si中
                ;计算高16位,将16位计算转化为32位计算
                 mov ax,dx
                mov dx,0
                div cx
                mov bx,ax         ;H/N存放在BX中
                ;计算低16位
                mov ax,si
                div cx
                
                mov cx,dx
                mov dx,bx
                ret
                
                
dneat:
                mov bx,0                         ;bx作为data段四字节数据的索引 (每次增加4)
                mov si,0                         ;si作为data段2字节数据的索引 (每次增加2)
                mov bp,0                        ;bp作为table段的索引 (table每次增加16)
                mov cx,21
dn_s:        
                ;拷贝
                ;table中每年的数据相隔F个字节
                ;table中同一年数据头索引 year(0)-summ(5)-ne(A)-??(D)
                ;                        长度(byte)          4       4       2      2        
                mov ax,ds:[bx]                                ;拷贝年份字符串 4 byte 每次2byte
                mov es:[bp],ax
                mov ax,ds:[bx+2H]        
                mov es:[bp+2H],ax        
                
                mov ax,ds:[bx+54H]                        ;拷贝收入字符串 dd=4byte 每次2byte
                mov es:[bp+5H],ax
                mov ax,ds:[bx+56H]
                mov es:[bp+5H+2H],ax        
                
                mov ax,ds:[si+0A8H]        
                mov es:[bp+0AH],ax                        ;拷贝雇员字符串        dw=2byte 
                
                ;除法计算会改变bx的值,先将bx入栈
                push bx
                ;计算平均收入
                ;load收入(4字节)
                mov ax,ds:[bx+54H]
                mov dx,ds:[bx+56H]
                ;load人数(2字节)
                mov bx,ds:[si+0A8H]
                div bx
                
                ;bx出栈
                pop bx
                ;保存计算结果(取整)(2字节)
                mov es:[bp+0DH],AX
                
                add bx,4H                        
                add si,2H
                add bp,10H                        
                loop dn_s
                ret
        
code ends
end start

DOS的汇编debug真的太不友好了,调试了三个多小时.....还发现前面几个测试点的程序里面的bug
课设1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-5 22:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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