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

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
  •  笨鸟学飞,勤习方飞.
  • 『姓名』:石冬                
  • 『性别』:保密  『发送消息
  • 个人说明:笨不是问题,笨不求知才是问题.
  • 详细信息『加为好友』
学习动态
最新留言

[2008-07-22 15:39] 推荐博文 课设一:要想快,讲规范,调试排错也关键!

图片载入中
-----------------------------------程序运行测试图----------------
课题分析:
一、数据
A、年份,4字节字符,须增加0结尾识别值;B、年收入总额,4字节数据,需转换成10进数字ASCII码,同时,因转10进制后其ASCII码占位最大需占用10位,加上结束识别位共占11位,共需占11字节,原4字节将远不能满足替换;C、年人数,2字节数据,转换后需占用6字节;D、年人均收益,因是dword/word计算求得,为防溢出,取与总额同位。
根据以上情况,原数据区空间,将难以保证数据转换ASCII后空间占位的需要,需另建适合的数据区,并拷贝数据。考虑到方便显示需要,数据构建以显示行方式排列。按预计最大占位计算,年份5字节,总额11字节,人数6字节,均数11字节,即每行应构建33字节,考虑到实际情况,均数不至于满位。因此,预留转换后数位缩减至10位,共留32字节,这样方便调试时,对数据区校验。数据区。db 672 dup(0) {21*32=672}
0~4:年份写入寻址0[...]; 5~15:总额写入寻址5[...];16~21:人数写入寻址16[...];22~31:均数写入寻址22[...];

二、表格结构
   Power idea basic situation of the company            表名
--------------------------------------------------------------                   
   year    Total_revenue    Employees  Both_revenue         表头
------------------------------------------------------------
01234567890123456789012345678901234567890123456789      参照标
   ****      **********       *****       *****         表体
   ****      **********       *****       *****   
   ****      **********       *****       *****   
------------------------------------------------------------       
Tabulation date:                    

三、程序结构模块
为方便调试和修改,应尽可能地让程序结构简单化,程序功能模块化。
㈠拷贝计算数据至新建数据区table段
㈡对和table段数据区的数值进行字符的ASCII转换,(注意每项均须以0结尾)
㈢按表结构将table段数据以字符方式写入显存

四、编程

assume cs:code,ds:data,SS:STACK
data segment 
        ;年份数据,84字节
        db "1975",'1976',"1977","1978","1979","1980","1981","1982","1983" 
        db "1984","1985","1986","1987","1988","1989","1990","1991","1992" 
        db "1993","1994","1995" 
        ;工资总额数据 84字节(21双字)
        dd 16,22,382,1356,2369,8000,16000,24486,50065,97479,140417,197514 
        dd 345980,590872,803530,1183000,1843000,2759000,3753000,4649000,59307000 
        ;人数数据 42字节(21字)
        dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 
        dw 11542,14430,15257,17800 
data ends 
table segment
        ;表格结构数组,开辟21组32字节的表格内存空间
        db 672 dup(0);21*32=672 
        db '     Power idea basic situation of the company    ',0
        db '--------------------------------------------------',0
        db '      year     Income       Number    Average ',0
table ends
STACK SEGMENT
        ;开辟64字节栈段空间
        Dw 32 DUP(0)
STACK ENDS

code segment
pro_end:
        mov ax,4c00h
        int 21h

;*****************************
;***构建数值字符转换数据区****
;*****************************
;按每32字节写一组数据,将数据源
;写入数据区备转换用
start:
        mov ax,data
        mov ds,ax
        MOV AX,TABLE
        MOV ES,AX
        MOV AX,STACK
        MOV SS,AX
        MOV SP,64
        MOV CX,21        
        mov bx,0H   ;读取双字单元寻址增量
        mov si,0H   ;读取字单元寻址增量
        mov di,0H   ;写入单元寻址增量

  s1:        PUSH 00h[bx]    ;读年份数据入栈
        PUSH 02h[bx]
        POP ES:02H[di]  ;年份字符数据出栈写入table(4B)
        POP ES:00H[di]  
        mov byte ptr es:04h[di],0H    ;字符窜结尾补0(1B)

        MOV AX,054H[bx]      ;读总额
        MOV DX,056H[bx]
        mov ES:05[di],AX     ;总额写入(4B,为转换应准备共11B)
        mov ES:07[di],DX
;............................以上数据为双字单元用BX寻址
        push cx              ;为防除法溢出调divdw子程
        mov cx,0A8H[si]
        call divdw           ;读年度人数,计算年人均工资
        pop cx
        push 0A8h[si]                 ;人数读写(2B为转换应准备共6B)
        pop ES:16[di]
        mov es:22[di],AX ;人均工资写入(2B为转换应准备共11B)
        mov es:24[di],dx
;............................以上为字单元用SI寻址
        add bx,04h     ;读年字符与总额时增量为4字节
        add si,02H     ;读人数与均收益时增量为2字节
        add di,32      ;写数据时每行数据间为32字节增量
        loop s1
;[end]

;***************************
;*****数据区数值字符转换******
;***************************
;更改数据段址,对应新建数据区

        mov ax,table
        mov ds,ax
        mov cx,21
        mov bx,0
        mov di,0
por_d_w:
        
        mov si,bx        ;总额换ASCII码
        add si,5
        mov ax,5[bx]
        mov dx,7[bx]
        call dtoc32

        mov si,bx        ;人数换ASCII码
        add si,16
        mov ax,16[bx]
        mov dx,0
        call dtoc32

        mov si,bx        ;均额换ASCII码
        add si,22
        mov ax,22[bx]
        mov dx,24[bx]
        call dtoc32
        add bx,32
        loop por_d_w 
;[end]


;***************************
;*****数据区字符写入显存******
;***************************
;显存段址:0b800H
;首页:0~24行,0~79列
;显示行设置:0行表题,1行注释线,2行表头,
;                 3~24行表体
;显示列设置:6~9列:年份;16~26列 总额;
;            30~35列人数;40-50列 均数
;数据区:段址 table。
;起始单元si:年份00+行*32;总额05+行*32;
;            人数16+行*32;均数22+行*32;        

        mov ax,table
        mov ds,ax
        mov cx,21
        mov bx,0
        mov dh,10
pro_show_start:
        push cx
        mov cx,00001010b 
        mov ax,32

        mul bl        ;年份写屏
        mov dl,6
        mov si,ax
        call show_str

        mov dl,16        ;总额写屏
        add ax,5
        mov si,ax
        call show_str

        mov dl,30        ;人数写屏
        add ax,11
        mov si,ax
        call show_str

        mov dl,40        ;均数写屏
        add ax,6
        mov si,ax
        call show_str        
        inc bx
        inc dh
        pop cx
        loop pro_show_start

        mov cx,00001100b ;表题写屏        
        mov dh,6
        mov dl,0
        mov si,672
        call show_str
        mov cx,00001111b ;表头线写屏
        mov dh,7
        mov si,723
        call show_str
        mov cx,00001111b ;表头栏写屏
        mov dh,8
        mov si,774
        call show_str
                         

        jmp pro_end ;转至程序结束点

;[end]

;*************************
;********★★★★★*********
;         子程序区
;********↓↓↓↓↓↓↓↓↓*********
;********↓↓↓↓↓↓↓↓↓*********

;********************************************
;入口:Dtoc32
;功能:将DWord数据转化为10进制的字符窜。并以单元数值
;        0做结尾符。
;入参:DX=预转为10进制的数据高16位,AX=预转为10进制的
;        数据低16位,字型。DS:si指向存放字符窜的首地址。
;回参:无
;********************************************
dtoc32:
        push ax
        push bx
        push cx
        push dx
        push di
        push si

        mov bx,0
        mov di,si
dtoc32_s:
        mov cx,10
        call divdw ;dx高16位;ax低16位;cx余数
        add cx,30h
        mov ds:[si],cl
        inc si
        inc bx
        mov cx,ax
        jcxz dtoc32_end
        jmp dtoc32_s
dtoc32_end:

        mov cx,bx
        mov si,di
dtoc32_f1:        
        mov al,ds:[si]
        push ax
        inc si 
        loop dtoc32_f1

        mov cx,bx
        mov si,di
dtoc32_f2:        
        pop ax
        mov ds:[si],al
        inc si
        loop dtoc32_f2
        mov byte ptr ds:[si],0H


        pop si
        pop di
        pop dx
        pop cx
        pop bx
        pop ax
        ret
;[end]

;***********************************************
;入口:DIVDW
;功能:进行不会溢出的DWORD/WORD除法。
;入参:dx=被除数高16位;ax=被除数低16位;
;      cx=16位除数,适用被除数DWORD,除数WORD。
;回参:dx=商的高16位;ax=商的低16位;cx=余数
;***********************************************
divdw:        
        push bx

        mov bx,ax
        mov ax,dx
        mov dx,0h
        div cx
        push ax
        mov ax,bx
        div cx
        mov cx,dx
        pop dx

        pop bx
        ret
;[end]

;*************************************************
;名称:show_str  入口标号
;功能:在指定行与列,按指定属性,显示一个以0结尾的字符窜。
;入参:DH=行号(0-24),DL=列号(0-79),CL=显示属性,
;      DS:SI指向字符窜首地址
;回参:无
;*************************************************
show_str:        
        push ax
        push bx
        push cx
        push dx
        push es
        push di
        push si
        
        mov bx,0h
        mov ax,160
        mov bl,dh
        mul bl
        mov bl,dl
        add bx,bx
        add ax,bx
        mov bx,ax
        mov ax,0b800h
        mov es,ax
        mov di,0
        mov dh,cl
show_str_s:
        mov cl,ds:[si]
        jcxz show_str_end
        mov dl,cl
        mov es:[bx+di],dx
        inc si
        inc di
        inc di
        jmp short show_str_s
show_str_end:
        pop si
        pop di
        pop es
        pop dx
        pop cx
        pop bx
        pop ax
        ret
;[end]        



code ends
end start
评论次数(18)  |  浏览次数(3474)  |  类型(实验报告) |  收藏此文  | 

[  deepblue   发表于  2008-07-22 15:52  ]

看着挺享受的,赞一个!

楼主的进度可以啊,再来的时候怕是已经学完了吧。

[  asm_sande   发表于  2008-07-22 16:01  ]

谢谢鼓励,
不过,现在是愈来愈慢了。关键,所有的题目都是自己思考后做的。我通常是做完后,再看别人的同进度练习和作业,这样理解更能深入些。~0~

[  jason_r   发表于  2008-07-22 16:17  ]

我刚进入!还在学基础知识!!大哥多提携一下!!

[  tomato   发表于  2008-07-22 16:35  ]

博主的作业做的真棒!还有这篇博客的标题!赞不绝口!

[  游客   发表于  2008-07-22 21:50  ]

博主好像是第一个给这个设计一的运行界面加上修饰和说明的人!!
足以表明博主学习的一颗红心啊!

[  游客   发表于  2008-07-23 19:41  ]

不求最快 但求有得

[  游客   发表于  2008-07-24 11:45  ]

规范书写利于调试除错.

[  gzgzlxg   发表于  2008-08-01 23:03  ]

就这样的代码也能称为规范?
连门都没有入,别在这里误人子弟了。
gzgzlxg

[  starrynight   发表于  2008-08-01 23:27  ]

是写与不写的区别
不是怎么写的问题

[  asm_sande   发表于  2008-08-02 20:17  ]

呵呵,gzgzlxg批评也许有点道理,偶本来就是初学,理解上还很粗浅,除了编写的代码本身问题、还有在编程思想上也需要在学习中的逐步培养.所有这些都是需要你给予指导的地方。不过你只是这么说一句,而不给出那怕是一点点具有实质性的批改意见。这就如对正在摸着石头过河的人说,别过河了一样,没有任何好处。希望gzgzlxg有时间能写点对我们新手有点实质性帮助的文字。

[  tjtchly   发表于  2008-08-21 12:56  ]

呵呵,gzgzlxg批评也许有点道理,偶本来就是初学,理解上还很粗浅,除了编写的代码本身问题、还有在编程思想上也需要在学习中的逐步培养.所有这些都是需要你给予指导的地方。不过你只是这么说一句,而不给出那怕是一点点具有实质性的批改意见。这就如对正在摸着石头过河的人说,别过河了一样,没有任何好处。希望gzgzlxg有时间能写点对我们新手有点实质性帮助的文字。
----------------------------------------
博主说得对,老鸟也有一个当菜鸟的过程。
别以为自己什么都懂,要知道,天外有天,人外有人,强中自有强中手。
现在偶还看不懂,才开始呀,属真正的菜菜,待看得懂时一定好好学学。

[  changkong   发表于  2008-09-17 13:25  ]

向博主学习!

[  panwei   发表于  2008-09-20 11:27  ]

向博主学习!

[  游客   发表于  2008-10-04 10:29  ]

;年份数据,84字节 
db "1975",'1976',"1977","1978","1979","1980","1981","1982","1983"  
db "1984","1985","1986","1987","1988","1989","1990","1991","1992"  
db "1993","1994","1995" 
呵呵,有些啰嗦,要是1000年呢?

1、书写还不错,程序中立即数最好用等价指令在程序开始定义一下,便于阅读。
2、规范度尚且不够,没达到错落有致(不过上传上来变形的情况可以理解)。
2、在命令提示符下编程,32位指令也可以使用。
3、每行语句后还可以更详细注释,不信你过2年再看你的程序,你自己都会耗费很大力气的。

最后,鼓励一下!(http://www.programbbs.com/bbs/  汇编语言专区cnhanxiao)

[  游客   发表于  2008-10-27 23:21  ]

感谢搏主如此精彩的讲解.

[  aimy   发表于  2008-11-28 19:30  ]

最后怎么执行啊,我用DEBUG执行,最后的-G还在上面,不能像你那样后面什么都没有

[  mess   发表于  2008-12-05 14:35  ]

到了第九章能屏幕显示东西了,可以直接运行看看程序的正确性了~
如上面这样,当然debug仍然很重要,尤其是排错的时候~

[  游客   发表于  2009-05-31 19:47  ]

想问问,假如把年份的数据由四位改为六位。如将1975改为600000,1976改为600001……依次类推。相应修改了程序,但运行不了,想请教一下,初学者,呵呵,很多都不太懂。

 
 请输入验证码  (提示:点击验证码输入框,以获取验证码