湖南农业大学课程设计报告
学  院:信息科学技术学院  班  级:2011级计算机1班 姓  名:钟雄辉学  号:201141842117 课程设计题目:代码转换程序设计 课程名称:汇编语言与微机原理 评阅成绩: 评阅意见:
成绩评定教师签名: 日期:    年    月    日
目录
概述„„„„„„„„„„„„„„„„„„„„„„1 一 设计内容与要求„„„„„„„„„„„„„„„1 二 设计思想„„„„„„„„„„„„„„„„„„„1 三 程序流程图„„„„„„„„„„„„„„„„„2 四 程序源代码„„„„„„„„„„„„„„„„„3 五 设计过程中遇到的问题及解决方法„„„„„„„„7 六 设计心得„„„„„„„„„„„„„„„„„„„7
代码转换程序
概述
代码转换程序实现了五个功能,用户可以根据自己的需要使用对应的功能,该程序实现了大小字母的转换,以及二进制数与十六进制数之间的相互转换,以及十六进制数转换成十进制数的功能。
一、设计要求
完成一个字母或数制之间的转化程序,主程序分别具有 5 种可选择的子功能,按相应的字符,可分别进入相应的子功能并在屏幕上显示结果,按“q”键退出。
5 种可选择的子功能分别为:
1)实现小写字母向大写字母的转换 2)实现大写字母向小写字母的转换 3)实现二进制数向十六进制数的转换  4)实现十六进制数向二进制数的转换 5)实现十六进制数向十进制数的转换  二、设计思想
1.实现大小写字母的转换只需要根据大小写字母的ascii码值相差32,将小写转换成大写时,只需要将小写字母的值减去32即可转换成大写字母,大写字母转换成小写字母时,只需要将大写字母加上32即可转换成小写字母
2.实现二进制数转换成十六进制数,要以读字符串的方式输入一个01字符串,判断哪些位是1,然后将对应的权值加到eax寄存器里面,即可将二进制数转换成十进制数并存放到eax寄存器里面,然后调用io32/inc文件提供的disphd,一十六进制的形式将eax的内容打印出来,便实现了二进制是转换成十六进制数。
3.将十六进制数转换成二进制数,只需要调用io32.inc提供的readhd从键盘读入一个十六进制的数到eax寄存器,然后以向左移位的方式,逐位移动到cf标志寄存器,判断cf寄存器是0还是1,打印对应的数字,知道32位都打印完毕
4.将十六进制数转换成十进制,只需要调用io32.inc文件提供的readhd函数从键盘读入8位十六进制的数到eax,然后调用io32.inc文件提供的dispsid函数以十进制的方式打印eax寄存器里面的内容即可。
第1页
三、程序流程图
输入1 调用 smtobig 输入2 调用bigtosm 输入q 开始 输入其它 输入数字并判断  输出错误信息 输入3 调用bintohec 输入4 调用hectobin 输入5 调用hectode   直接将输入字 母的ascii码值减掉32后输出        直接将输入字母的ascii码加上32后输出   调用getlength获得输入串的长度,转换输入的二进制数为十进制,以十六进制形式打印 调用readhd读入一个十六进制数,以移位的形式一位一位输出各二进制位  调用readhd读入十六进制的数,调用dispsid以十进制形式打印   结束
图1-1 主模块的逻辑图
第2页
四、程序源代码
include io32.inc .data
msg byte '请输入对应功能前面的数字: ',13,10,0 msg1 byte '请输入小写字母(a-z): ',0 msg2 byte '请输入大写字母(A-Z): ',0
msg3 byte  '请输入一个二进制数(长度小于33): ',0 msg4 byte  '请输入一个十六进制数:(长度为8) ',0 msg5 byte '转换结果为: ',0
errmsg byte '您输入的字母不正确,请重新输入',13,10,0 fun1 byte '1.小写字母转换成大写字母',13,10,0 fun2 byte '2.大写字母转换成小写字母',13,10,0 fun3 byte '3.二进制数转换成十六进制数',13,10,0 fun4 byte '4.十六进制数转换成二进制数',13,10,0 fun5 byte '5.十六进制数转换成十进制数',13,10,0 fun6 byte 'q.退出程序',13,10,0 bin byte 32 dup('0') result byte 8 dup('0') .code start:
moveax,offsetmsg  ;打印提示用户输入选择的信息 calldispmsg
moveax,offset fun1  ;显示功能菜单 calldispmsg
moveax,offset fun2 calldispmsg
moveax,offset fun3 calldispmsg
moveax,offset fun4 calldispmsg
moveax,offset fun5 calldispmsg
moveax,offset fun6 calldispmsg again:
call readc   ;用户输入选择的功能 calldispcrlf cmp eax,'1' jne next1
call smtobig   ;调用小写字母转换成大写字母的函数jmp start  next1:
cmp eax,'2' jne next2
第3页
call bigtosm   ;调用大写字母转换成小写字母的函数 jmp start next2:
cmp eax,'3' jne next3
call bintohec   ;调用2进制数转换陈16进制数的函数 jmp start next3:
cmp eax,'4' jne next4
call hectobin   ;调用16进制数转换2进制数的函数 jmp start next4:
cmp eax,'5' jne next5
call hectode    ;调用16进制数转换成10进制数的函数 jmp start next5: cmpeax,'q'
je over            ;用户输入q,退出程序 moveax,offseterrmsg   ;打印提示输入错误的信息 calldispmsg
jmp again        ;使用完一个功能后继续回到主菜单 over: exit 0
;小写转换成大写子程序 smtobigproc
moveax,offset msg1    ;打印提示用户输入要转换的小写字母 calldispmsg
call readc     ;用户输入一个小写字母 calldispcrlf
sub eax,32       ;将小写字母的ascii码值减去32转换成大写字母push eax     ;将结果先压栈保存 moveax,offset msg5    ;打印输出信息 calldispmsg
pop eax      ;将结果弹栈
call dispc     ;打印转换成的大写字母 calldispcrlf ret
smtobigendp
;大写转换成小写子程序 bigtosmproc
第4页
moveax,offset msg2     ;打印提示用户输入要转换的大写字母 calldispmsg
call readc     ;用户输入一个大写字母 calldispcrlf
add eax,32       ;将用户输入的大写字母的ascii码值加上32转换成小写字母 push eax      ;将结果先压栈保存 moveax,offset msg5    ;打印输出信息 calldispmsg
pop eax      ;将结果弹栈
call dispc        ;打印转换成的小写字母 calldispcrlf ret
bigtosmendp
;二进制转换成16进制子程序 bintohecproc
moveax,offset msg3    ;打印提示输入信息 calldispmsg
moveax,offset bin     ;把二进制数输入bin数组 callreadmsg
moveax,offset msg5    ;打印输出结果提示 calldispmsg
call getlength     ;edx里面保存输入的字符串的长度 movesi,offset bin
mov ecx,1       ;用来计算二进制位的对应的权值 mov eax,0        ;存放转换成的十进制数
do:          ;将输入的二进制数转换成10进制数并存到eax里面decedx      ;2进制数字串的指针前移
cmp edx,-1       ;判断整个二进制数字串是否处理完毕 je over1
movbl,[esi+edx]     ;将对应位的值存到bl寄存器 cmp bl,'1'         ;判断全职是否为1 jejia
add ecx,ecx     ;ecx翻倍,目的是计算对应位上的权值 jmp do  jia:
add eax,ecx     ;为1就将对应的权值加到eax寄存器 add ecx,ecx     ;ecx翻倍 jmp do  over1:
call disphd     ;将结果以16进制的形式打印 calldispcrlf ret
bintohecendp
第5页
;十六进制转换成二进制子程序 hectobinproc mov ecx,0
moveax, offset msg4    ;打印提示输入一个16进制数 calldispmsg
call readhd     ;输入十六进制的数 calldispcrlf
movebx,eax     ;将输入暂时存到ebx
moveax,offset msg5    ;打印输出结果的提示信息 calldispmsg continue: incecx
cmp ecx,32      ;判断是否32个数位都打印完成 jg over3
sal ebx,1       ;eax左移一位到cf寄存器 jnc print0      ;cf寄存器为0就打印0 mov eax,1         ;否则打印1 calldispuid
jmp continue        ;继续打印 print0:                   ;打印 mov eax,0 calldispuid
jmp continue        ;继续移位打印 over3:
calldispcrlf ret
hectobinendp
;获得输入的字符串的长度子程序 getlengthproc
mov edx,0       ;edx用来保存字符串的长度
movesi,offset bin       ;取得输入的二进制数字的偏移地址again2:
cmp byte ptr [esi],0   ;判断是否到了字符串结尾 je over2
incedx     ;长度加1
incesi        ;字符串指针后移 jmp again2 over2: ret
getlengthendp
第6页
;十六进制转换成十进制子程序  hectodeproc
moveax,offset msg4      ;打印提示输入一个16进制的数 calldispmsg
call readhd      ;从键盘读入一个8位16进制的数 calldispcrlf
movebx,eax       ;将输入暂时存到ebx寄存器 moveax,offset msg5    ;打印提示结果输出 calldispmsg
moveax,ebx       ;将输入的十六进制数存到eax
call dispuid    ;以十进制的方式打印十六进制数 calldispcrlf ret
hectodeendp end start
五、设计过程中遇到的问题及解决方法
该程序的第一二个功能比较容易实现,在实现第三个功能的时候,先是打算以读字符串的形式读入一个二进制数字串,然后,每取四位算出对应的十六进制权值,直到整个字符串处理完毕,不过这样做,循环和跳转太多,调试了很久,还是没找到错误,便决定换一种方式来做,想到教材上面提供的io32.inc文件里面有一个disphd的函数可以直接以十六进制的形式打印eax寄存器里面的内容,于是想干脆先把输入的二进制数字串转换成对应的十进制数存到eax寄存器里面,然后直接调用disphd打印就可以了,减少了很多麻烦。然后接着就很轻松的解决了第四五个功能,因为io32.inc文件里面有提供对十六进制数的输入输出函数。
六、设计心得
本次实验设计的重点点是将不同进制的输入输出分别写成功能不同的函数。通过这次的课程设计,我对数制转换的原理有了叫较为清楚的理解,可以解释原来并不懂的程序和代码,对应各种寄存器的跳转有了一定的了解,同时认识到由于寄存器的数量有限,我们有时侯不得不进行出栈和入栈了,这样可以解决有时候寄存器不够的情况。 在一开始,我只能一个程序实现一个功能,要想把它们都连起来,需要进行段间调用,经过和同学的探讨和在网上查找资料,有了一点理解,但是做起来很复杂,有的时候一点点的失误,就会导致整个程序不能正常运行,而且代码很繁琐。然后经过许多的思考,让我知道,一个程序也可以实现这些所有的功能,相对于我之前做的,简单很多,而且运行起来也很方便,不用每一个模块程序都进行编译和链接。
第7页
通过完成本次课程设计,可以进一步对学习汇编有一定的推动作用,对汇编基础也有了一定的提高,这个课程设计也让我把汇编重新学习了一遍。
通过这个课程设计,我对汇编有了一定的体会,因为汇编是可以直接和机器打交道,从而使得汇编语言的效率很高,处理相同的程序比高级语言速度快很多,但是他操作也没有高级语言那么方便。
第8页