汇编语言程序设计-课程设计.docx
汇编语言程序设计-课程设计 一、实验目的 1.熟练掌握call、ret的原理及应用 2.熟练掌握子程序的框架、进行模块化程序设计 3.掌握参数与结果的传递、批量数据传递等问题的解决方法 二、实验内容及要求 (一)综合程序设计:利用实验10中的三个子程序,将power idea公司的数据按照下图所示的格式在屏幕上显示出来,要求计算人均收入并显示出来。 power idea公司的数据如下: assume cs:codesg 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' ;年份 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 ;公司雇员人数 data ends table segment db 21 dup('year summ ne ?') 要求: (1)给出该设计过程或算法 (2)在代码中必要的地方给出相应注释 (3)最终显示结果。 三、实验解答过程及结果 (1)该题目的第一段db型年份数据是以字符串储存的,不适合后续的操作,所以先用ice子程序把年份数据转化为word型数据。接下来循环开始,先调用dtoc1子程序,把第一年(1975)的word型年份数据转化为字符串储存在es 中,再调用show_str函数在屏幕缓冲区显示出来。接着调用dtoc2子程序和show_str子程序把第一年的收入在同一行显示出来。再接着调用dtoc1子程序和show_str子程序把第一年的雇员数在同一行显示出来,最后计算平均收入,同样调用两个子程序显示出来。不停地循环,循环21次,把所有的数据都显示出来,输入程序结果,程序完结。 (2)代码及数据如下: assume cs:codesg 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' ;年份 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 ;公司雇员人数 table segment db 21 dup('year summ ne ? ') table ends stack segment db 1024 dup(0) stack ends codesg segment start:mov ax,data mov ds,ax mov ax,table mov es,ax mov ax,stack mov ss,ax mov sp,1024 mov si,0 mov bx,0 mov dh,5 mov ax,1975 ;初始化,dh为输出时的行数 so:call ice push ax mov ax,ds:si call dtoc1 pop ax push cx mov dl,1 mov cl,00000111b call show_str pop cx ;这两段输出年份 push ax push dx mov ax,ds:si+84 mov dx,ds:si+86 call dtoc2 pop dx pop ax push cx mov dl,8 call show_str pop cx ;这两段输出收入 push ax mov ax,ds:bx+168 call dtoc1 pop ax push cx mov dl,18 mov cl,00000111b call show_str pop cx ;这两段输出雇员数 push ax push dx mov ax,si+84 mov dx,si+86 div word ptr ds:bx+168 ;计算人均收入,结果为16位,保存在ax中 call dtoc1 pop dx pop ax push cx mov dl,26 mov cl,00000111b call show_str pop cx ;这两段输出平均收入 add si,4 add bx,2 inc dh inc ax loop so ;循环21次,增加参数 mov ax,4c00h int 21h ;名称:ice ;功能:在ds:si开始,以“数据”“0”的格式用新数据替换旧数据(即年份字符串);参数:(ax)=word型的数据,es:si指向字符串的首地址 ;返回:无 ;说明:把字符串的年份转化为word型数据,并以0结尾,方便dtoc1函数的调用 ice:push bx mov ds:si,ax mov bx,0 mov ds:si+2,bx ret ;名称:dtoc1 ;功能:将一个word型数转化为字符串,数应不大于65535 ;参数:(ax)=word型的数据,es:si指向字符串的首地址 ;返回:es:si放此字符串,以0结尾 ;说明:因为ds放了数据段,为免混淆,把字符串放在es里,下面的函数也相同dtoc1:push cx push bx push dx mov dx,0 push di push si mov di,0 cir1:mov cx,10 div cx add dx,30h mov bx,dx push bx inc di mov dx,0 mov cx,ax jcxz ow jmp short cir1 mov es:si,bx inc si loop s pop si pop di pop dx pop bx pop cx ret ;名称:dtoc2 ;功能:将一个dword型数转化为字符串,数不应大于FFFFFFFFFFFFFFFF ;参数:(ax)=dword型的数据的低16位,(dx)=dword型的数据的高16位,es:si 指向字符串的首地址 ;返回:es:si放此字符串,以0结尾 dtoc2:push cx push bx push si push di mov di,0 cir2:mov cx,10 call divdw add cx,30h mov bx,dx add bx,ax mov cx,bx jcxz ox jmp short cir2 ox:mov cx,di s8:pop bx mov es:si,bx inc si loop s8 pop di pop si pop bx pop cx ret ;名称:divdw ;功能:除法,被除数32位,除数16位,商32位,余数16位,不会溢出;参数:(dx)=被除数高16位,(ax)=被除数低16位,(cx)=除数;返回:(dx)=商高16位,(ax)=商低16位,(cx)=余数 divdw:push bx push ax mov bx,ax pop ax div cx mov cx,dx mov dx,bx pop bx ret ;名称:show_str ;功能:在指定的位置,用指定的颜色,显示一个用0结束的字符串 ;参数:(dh)=行号(125),(dl)=列号(180),(cl)=颜色,es:si指向字符串的首地址 ;返回:无 show_str:push di push si mov di,0 push ax push dx dec dh dec dl ;这里采用习惯上的叫法,放在显示缓冲区最开头就是1行1列 mov al,160 ;1行80个字符,一个字符2个字节 add dl,dl ;一个字符2个字节 mov dh,0 add dx,ax add di,dx ;这几行是为了计算字符串首的偏移地址 mov ah,cl ;字符的高位保存属性,低位保存数据 push cx change:mov cl,es:si mov ch,0 jcxz ok mov al,es:si push es push ax mov ax,0b800h ;显示缓冲区的空间为B8000HBFFFFH mov es,ax pop ax mov es:di,ax ;输出到缓冲区 pop es inc si add di,2 jmp short change ok:pop cx pop dx pop ax