. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->CALL和RET指令
主题 : :  课程设计1—完成—Mark  [待解决] 回复[ 12次 ]   点击[ 947次 ]  
kamjia
[帖 主] [ 发表时间:2010-11-09 11:50 ] 
荣誉值:1
信誉值:2
注册日期:2009-05-25 18:12
经过好几天的痛苦挣扎,总算把课程设计1给完成了,呵呵,自己觉得程序可能有点儿啰嗦,但是,思路还比较清晰,发出来大家看看吧,自己也留下个脚印……

下面啰嗦一下这几天的总结:
1.子程序使用寄存器前一定要保存,避免在主程序中被调用时由于数据覆盖造成错误,其错误发现比较困难;
2.写程序时要养成写注释的好习惯,避免在程序调用的时候方便,同时以后在读程序时,让人快速理解程序的思路和流程;
3.程序的模块儿化优势:各个子程序功能分解,易于优化和扩展,方便调用
4.还有就是debug,虽然麻烦,但是很有效

就这些吧,具体还有好多体会,表达能力欠佳,就说这些吧···

下面是我的源代码(已测试结果无误):

assume cs:code,ds:data,ss:stack

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个字符(共84个字节,0-53H)
                                
                                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型数据(共84个字节,54H-A7H)
                                
                                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型数据(共42个字节,A8H-D1H)
        
data ends

stack segment

                                dw 80 dup (0)                ;定义栈段来暂存数据
                                
stack ends

table segment

                                db 672 dup (0)    ;定义21X32个字节来存放整个数据段的所有数据
                                
table ends

code segment

;-------------------------------------------------------------------------------------------
;                                                                                程序开始,初始化各段和寄存器
;-------------------------------------------------------------------------------------------
start:                mov ax,stack                        
                                mov ss,ax
                                mov sp,0a0h

                                mov ax,data
                                mov ds,ax
                                
                                mov ax,table
                                mov es,ax
                                
                                mov si,0
                                mov di,0
                                mov bx,0
                                
;-------------------------------------------------------------------------------------------
;                                                        将各项数据存入进table段中,以便稍后进行格式化
;-------------------------------------------------------------------------------------------                                
                                mov cx,21
loop1:                mov ax,0[bx]                                                ;将年份存入table段中,以0结束
                                mov dx,2[bx]
                                mov es:0[di],ax
                                mov es:2[di],dx
                                mov BYTE ptr es:4[di],0h
                                
                                mov ax,54h[bx]                                                ;将总收入存入table段中,以0结束
                                mov dx,56h[bx]
                                mov es:5[di],ax
                                mov es:7[di],dx
                                mov BYTE ptr es:15[di],0h
                                
                                mov ax,0a8h[si]                                        ;将雇员人数存入table段中,以0结束
                                mov es:16[di],ax
                                mov BYTE ptr es:21[di],0h
                                
                                mov ax,54h[bx]                                                ;计算出人均收入并存入table段中,以0结束
                                div word ptr ds:0a8h[si]                
                                mov es:22[di],ax
                                mov BYTE ptr es:32[di],0h
                                
                                add bx,4                                                                ;定位到下一个data段中的数据项
                                add di,32                                                        ;定位到下一个table段中的行
                                add si,2                                                                ;定位到下一个table段中的列
                                loop loop1
                                
;-------------------------------------------------------------------------------------------
;                                        格式化table段中的数据,将将之从第行第列开始显示到屏幕上
;-------------------------------------------------------------------------------------------                        
                                mov ax,table
                                mov ds,ax
                                mov si,0
                                
                                mov cx,21                                                        ;用循环将年份显示到第5行第1-11列
                                mov dh,5
                                mov dl,1
year:                        push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop year
;----------------------------------------------------------------------------
;格式化总收入数据,并显示到第5行第12-22列
                                
                                mov cx,21
                                mov bx,5
tot_inco_1:        mov ax,ds:[bx]
                                mov dx,ds:2[bx]
                                call dtoc32
                                add bx,20h
                                loop tot_inco_1
                                
                                mov cx,21
                                mov si,5
                                mov dh,5
                                mov dl,12
tot_inco_2:        push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop tot_inco_2

;----------------------------------------------------------------------------
;格式化雇员人数数据,并显示到第5行第23-33列
                                mov cx,21
                                mov bx,16
emp_1:                mov ax,ds:[bx]
                                mov dx,0
                                call dtoc32
                                add bx,20h
                                loop emp_1
                                
                                mov cx,21
                                mov si,16
                                mov dh,5
                                mov dl,23
emp_2:                push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop emp_2
                                
;----------------------------------------------------------------------------
;格式化人均收入数据,并显示到第5行第34列

                                mov cx,21
                                mov bx,22
avg_inco_1:        mov ax,ds:[bx]
                                mov dx,0
                                call dtoc32
                                add bx,20h
                                loop avg_inco_1
                                
                                mov cx,21
                                mov si,22
                                mov dh,5
                                mov dl,34
avg_inco_2:        push cx
                                mov cl,2
                                call show_str
                                pop cx
                                inc dh
                                add si,20h
                                loop avg_inco_2
                                
                                mov ax,4c00h                                                ;程序结束,返回
                                int 21h
;-----------------------------------------------------------------------------------
;说明:将dword型数据转变为表示十进制的字符串,字符串以0为结尾符
;参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,ds:si指向字符串的首地址
;返回:无
;-----------------------------------------------------------------------------------
dtoc32:                push dx                                ;将子程序里可能用到的寄存器入栈保存
                                push ax
                                push cx
                                push bx
                                push si
                                push di
                                
                                mov di,0                                ;;初始化di做计数器
                                
s1:                        mov cx,10
                                call divdw                        ;调用子程序divdw来做除法运算,求余
                                push cx                                ;将余数入栈保存
                                mov cx,dx
                                jcxz s2                                ;判断商的高16位是不是0,如果高16位是0则跳转到s2处去判断低位,不是0则继续执行
                                pop cx                                ;将余数出栈,做修改
                                add cx,30h
                                push cx                                ;再次将余数入栈保存
                                inc di                                
                                jmp short s1                ;跳到s1断续做除法
                                
s2:                        mov cx,ax                        ;判断商的低16位是不是0,如果低16位是0则跳转到s3处去,若不是0则继续执行
                                jcxz s3
                                pop cx
                                add cx,30h
                                push cx
                                inc di
                                jmp short s1                
                                
s3:                        pop cx                                ;由于结果的商即使是0,也要将当前的余数做修改保存的处理,则此处也要再一次做保存
                                add cx,30h
                                push cx
                                inc di
                                
                                mov cx,di
                                mov si,0
s4:                        pop ax
                                mov ds:[si][bx],al
                                inc si
                                loop s4
                                
                                mov BYTE ptr ds:[bx][si],0        ;在最后一位加入一个0来标识字符处理结束
                                jmp short ok
                                
ok:                        pop di
                                pop si
                                pop bx
                                pop cx
                                pop ax
                                pop dx
                                ret
                                
;-------------------------------------------------------------------------------------------                                        
;说明:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
;参数:(ax)=dword型数据的低16位,(dx)=dword型数据的高16位,(cx)=除数                        
;返回:(dx)=结果的高16位,(ax)=结果的低16位,(cx)=余数
;-------------------------------------------------------------------------------------------

divdw:                push bx                        ;将bx的值入栈保存
                                push ax                        ;先将低16位压栈保存

                                ;先计算高位除法
                                mov ax,dx                ;将高16位的数据放到ax中,做为被除数的低16位,来做16位除法运算
                                mov dx,0                        ;将被除数的高16设0处理
                                div cx
                                mov bx,ax           ;将商保存在bx寄存器中(此商稍后将会做为最后结果的高16位)
                                
                                ;再计算低位除法   
                                pop ax                        ;将之前压入栈的原数低16位的数据出栈
                                div cx
                                mov cx,dx                ;除法完成之后,将余数保存到cx中
                                mov dx,bx                ;将之前高位除法算的商放到dx中,做为结果的高16位(默认低16位已存放到了ax当中)
                                pop bx                        ;将bx的值还原
                                ret 

;----------------------------------------------------------------------------------------------------
;说明:在指定的位置,用指定的颜色,显示一个用0结束的字符串
;参数:(dh)=行号(0`24),(dl)=列号(0`79),(cl)=颜色,ds:si指向字符串的首地址
;结果:无返回值
;----------------------------------------------------------------------------------------------------
show_str:        push ax
                                push bx
                                push cx
                                push dx
                                push bp
                                push si
                                push di
                                
                                mov ax,0b800h
                                mov es,ax
                                mov di,0
                                
                                ;算出指定的位置的偏移地址
                                mov ax,0   
                                mov al,160                                ;每行有160个字节
                                dec dh                                        ;用行数减1乘以160个字节,算出整行的字节数
                                mul dh
                                mov bx,ax                                        ;将结果入栈保存起来
                                dec dl                                        ;将列减1乘以2得出第几列所占的字节数(显示1个字符需要用2个字节)
                                mov al,2
                                mul dl
                                add bx,ax                                ;将两数的结果相加,得出所规定的行、列所的偏移地址
                                
                                mov dl,cl                            ;因为S标号下将会用到CX值的判断,所以,在运行之前,将提供颜色值的寄存器CL保存下来
                s0:        mov cl,[si]
                                mov ch,0
                                jcxz return
                                mov al,[si]                                ;ax低8位用来保存字符的ascii码
                                mov ah,dl                                ;ax高8位用来保存字条的颜色信息
                                mov es:[bx][di],ax        ;将保存了ascii码和颜色的字符信息写入显存区
                                inc si                                        ;定位到下一个字符
                                add di,2                                        ;定位到下一个显存位
                                jmp s0
                                        
        return:        pop di
                                pop si
                                pop bp
                                pop dx
                                pop cx
                                pop bx
                                pop ax
                                ret
        
code ends

end start
mayjian
[第8楼] [ 回复时间:2011-04-20 17:51 ] 
荣誉值:4
信誉值:0
注册日期:2011-04-12 20:28
编写任何程序,不仅要简洁,更要接口分明
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved