第十章课程设计1(完成版)
2009-09-05 17:37
113 查看
解题思路:结合实验七和第十章的实验三就可以实现程序。
在郁闷半天之后,静下心来之后分析知道是display段程序过长,所以把当中的显示年份、处理收入数据并显示、处理雇员人数并显示、处理平均工资并显示分成了四个子程序,在display中调用它们,结果证明实验成功。由此可见,分模块、分功能是很重要的编程思维方式。
assume cs:codesg datasg 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' dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514 dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000 dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226 dw 11542,14430,15257,17800 datasg ends table segment db 21 dup ('year summ ne ?? ') table ends data segment db 10 dup(0) data ends stacksg segment db 16 dup (0) stacksg ends codesg segment start: mov ax,datasg mov es,ax mov ax,table mov ds,ax mov ax,stacksg mov ss,ax mov sp,10h mov bx,0 mov si,0 mov di,0 mov cx,21 ;data_to_tablesg循环是为了把datasg段中的数据经过处理后放入table段,为了后面的输出做准备 data_to_tablesg: ;copy the year data push es:[bx] push es:[bx+2] pop ds:[si+2] pop ds:[si] ;copy the income data push es:[bx+54h ] push es:[bx+54h +2] pop ds:[si+7] pop ds:[si+5] ;copy the count of employees push es:[di+0a8h] pop ds:[si+0ah] mov ax,ds:[si+5] mov dx,ds:[si+7] div word ptr ds:[si+10] mov ds:[si+0dh],ax add di,2 add si,10h add bx,4 loop data_to_tablesg ;下面开始从table段中拿出数据,然后到显存段中输出,这里的思路是挨个输出table段中的数据 mov sp,10h;设置ss:sp指向stacsg栈段的栈顶 mov si,0;ds:[si]指向我们将要处理的数据的table段 mov ax,0b800h mov es,ax mov bx,0;设置es:[bx]为显示的缓存器的地址 mov cx,21;因为要处理的数据为21,所以循环次数为21 display: ;在每次循环一开始就计算该次循环所对应的行的显存段的偏移地址,结果存储到dx中 call calculate_line_value push bx push es push cx push di;因为下面的程序中将要用到es、bx、cx、di,所以这里先把他们入栈保存起来 call show_year ;因为在调用子程序时,已经改变了显存段的偏移地址,而为了对齐输出,我们必须确保每行的开始地址即di的值不能改变,所以入栈保护起来 pop di; push di add di,40;这是为了对齐输出,在输出收入数据应该从 call show_income pop di push di add di,80;输出完后,要把di的值恢复,再放到栈中保护起来,再设置该行的偏移地址 ;恢复ds指向table段,使其能继续取table段中的值 mov cx,table mov ds,cx call show_sum_employees pop di add di,120;输出完后,要把di的值恢复,再放到栈中保护起来,再设置该行的偏移地址 ;恢复ds的值 mov cx,table mov ds,cx call show_avarage_salary ;恢复ds的值 mov cx,table mov ds,cx ;在调用完子程序后要把cx、es、bx的值恢复给他们 pop cx pop es pop bx add bx,10h ;把bx的值加2使得es:[bx]能取得下一个数据 loop display mov ax,4c00h int 21h ;计算该次循环要显示的行号的开始地址 calculate_line_value: mov dh,24 sub dh,cl;这里是用24减去cl中的值就是该次循环要显示的行号,我设置成从第二行开始显示 mov dl,0;列号 ;我们在第九章的实验材料中知道显示的一行的偏移为0a0h mov al,0a0h dec dh;因为0a0h是第二行的开始,所以减去1后,比如要在第八行显示,就要7*0a0h,不减的话就是在第九行显示了 mul dh; mov di,ax;把上面乘积的值给我们使用的偏移地址的寄存器di ret ;这里是输出年份,因为年份已经是一字符的形式存储的,不需要在经过转换,所以直接输出 show_year: mov al,ds:[bx];去取data段的数据,这里bx是偏移量 call show_str_year;顾名思义,就是专门为输出年份所写的输出子程序 mov al,ds:[bx+1] call show_str_year mov al,ds:[bx+2] call show_str_year mov al,ds:[bx+3] call show_str_year ret ;下面是输出收入的数据,在输出后面的收入数据、雇员人数和平均工资时都要先把数字转换成对应的字符。再调用show_str_other子程序输出 ;这里的关键是运用定义的段data段来存放相应的数据如收入数据转换后的字符,然后马上输出。 show_income: mov ax,ds:[bx+5] mov dx,ds:[bx+7]; mov cx,data mov ds,cx;这里将要用到程序刚开始时定义的用来存放相应的数据如收入数据转换后的字符 mov si,10;设置ds:[si]用来存放从data段中取出的数据转换为对应字符串的值,特别注意这里ds中存放的是data段的段地址 mov byte ptr ds:[si],0;因为在调用dtoc子程序时得到的数据室逆序的,故我这里采用的是先填充末尾,倒着填过来。 call change_to_char;调用把数字转换成对应得字符的子程序,结果存储在data段中 call show_str_other;调用输出字符串子程序show_str_others输出change_to_char中存放在data段中的字符串 ret ;处理雇员人数并显示 show_sum_employees: mov ax,ds:[bx+10] mov dx,0; mov cx,data mov ds,cx mov si,10;设置ds:[si]用来存放从data段中取出的数据转换为对应字符串的值 mov byte ptr ds:[si],0;因为在调用dtoc子程序时得到的数据室逆序的,故我这里采用的是先填充末尾,倒着填过来。 call change_to_char call show_str_other ret ;处理雇员人数并显示 show_avarage_salary: mov ax,ds:[bx+13] mov dx,0; mov cx,data mov ds,cx mov si,10;设置ds:[si]用来存放从data段中取出的数据转换为对应字符串的值 mov byte ptr ds:[si],0;因为在调用dtoc子程序时得到的数据室逆序的,故我这里采用的是先填充末尾,倒着填过来。 call change_to_char call show_str_other ret ;把table段中的数据转换成对应的字符串 change_to_char: mov cx,ax;把ax的值给cx,借以判断ax中的值是否为0,因为ax中的值是除法中的商 jcxz changeOK;如果ax中的值为0,说明除法结束了 mov cx,10;把要现实的数据转换成十进制数对应的字符,所以基数是10 ;由于下面还要用到si和ax,所以先把他们的值给保存起来。 push si push ax ;下面就是除法不会溢出的公式的应用 mov ax,dx mov dx,0 div cx mov si,ax pop ax div cx mov cx,dx mov dx,si pop si add cx,30h sub si,1;每处理传进来的数据的每一位数据时,记得要把si减一以便ds:[si]指向下一个内存单元 mov ds:[si],cl jmp short change_to_char changeOK:ret ;输出单个字符的子程序 show_str_year: mov cl,0ah ;设置显示的字体颜色 mov ah,cl mov es:[di],ax add di,2 ret ;输出字符串的子程序 show_str_other: mov al,ds:[si] mov cl,al jcxz ok mov cl,0ah mov ah,cl mov es:[di],ax add di,2 inc si; jmp short show_str_other ok: ret codesg ends end start
在郁闷半天之后,静下心来之后分析知道是display段程序过长,所以把当中的显示年份、处理收入数据并显示、处理雇员人数并显示、处理平均工资并显示分成了四个子程序,在display中调用它们,结果证明实验成功。由此可见,分模块、分功能是很重要的编程思维方式。
相关文章推荐
- 《汇编语言》(第三版)王爽第十章 课程设计1 个人方法记录
- 王爽 汇编语言 课程设计1 独立完成
- 学习<<汇编语言 -王爽>>,自已完成的一道课程设计题 (5)
- 武汉大学计算机系。武汉大学是当时国内最早一批实施学分制的大学,按照学校要求,只要修完一定的学分就可以毕业。刚上大学,对自己要求比较严的雷军就开始选修了不少高年级的课程。仅用了两年时间,雷军修完了所有学分,甚至完成了大学的毕业设计。
- 使用netbeans完成的操作系统课程设计-设备管理模拟
- 王爽汇编第十章课程设计精简设计~(整理)
- 大一的第一篇的C语言课程设计完成了,链表的选择排序
- 网校搭建完成,课程还需要设计吗?
- 王爽《汇编语言》第十章 课程设计1 解答
- 期末课程设计之 c++操作mysql完成机票预订系统(vc 6.0配置mysql环境)
- 使用netbeans完成的操作系统课程设计----存储管理模拟
- 操作系统课程设计完成了
- 网校搭建完成,课程还需要设计吗?
- 某个课程设计时用到的SQL脚本,贴在这里供自己以后参考一下
- C语言课程设计 管理系统
- 单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》
- C语言连接MySQL数据库(课程设计总结)
- 课程设计__友元
- 课程设计两连发之中国象棋人机博弈
- 利用TCP/UDP完成文件传输的设计和实现