汇编代码转换程序(字母转换-进制转换)(共17页).doc
精选优质文档-倾情为你奉上湖南农业大学课程设计报告学 院:信息科学技术学院 班 级:姓 名: 学 号:课程设计题目:代码转换程序设计课程名称:汇编语言与微机原理指导老师:评阅成绩:评阅意见:成绩评定教师签名:日期: 年 月 日目 录概述 1一设计题目 1 二设计内容与要求 1 三设计思想 1 四程序流程图 3 五程序源代码 5 六设计过程中遇到的问题及解决方法 14七设计心得 15代码转换程序设计概述: 代码转换程序主要是实现字母间的转换和数值之间的转换。其中字母转换是大小写字母之间的互换,二进制转换则是二进制,十进制,十六进制之间的转换。程序设计成一个代码转换系统,给出一个可供选择的菜单,根据界面的信息选择不同的子功能。通过做这个程序,加强汇编语言编程的能力,更好的了解其基本原理,基本的思想,基本的方法以及相关的注意事项。一、 设计题目 代码转换程序设计二、 设计内容与要求 完成一个字母或数制之间的转化程序,主程序分别具有 5 种可选择的子功能,按相应的字符可分别进入相应的子功能并在屏幕上显示结果,按“q”键退出。5 种可选择的子功能分别为: 1)实现小写字母向大写字母的转换 2)实现大写字母向小写字母的转换 3)实现二进制数向十六进制数的转换 4)实现十六进制数向二进制数的转换 5)实现十六进制数向十进制数的转换三、 设计思想 运行程序,首先会显示主界面,用户可依据提示选择不同的编号,实现不同的子功能。 1、大写字母向小写字母的转换。当用户选择编号a,便选中了这一个子功能。通过判断标识符,程序跳转到标识符所在的位置。根据提示输入一个大写字母,会有一个判断输入是否合法的过程,若输入的是非大写字母,则会提示输入错误,请重新输入,直到输入正确为止。通过改变assic码值,实现大写字母向小写字母的转换。显示转换后的字母,然后跳转到主菜单。 2、小写字母向大写字母的转换。当用户选择编号b,便选择了这一个子功能。通过判断标识符,程序跳转到标识符所在的位置。根据提示输入一个小写字母,接下来判断其合法性,若输入的字母是非小写字母,则会提示输入错误,请重新输入,直到输入正确为止。通过改变assic码值,实现小写字母向大写字母的转换。显示转换后的字母后,跳转到主菜单。 3、二进制向十六进制的转换。当用户选择编号c,便选择了这一个子功能。通过判断标识符,程序跳转到标识符所在的位置。根据提示首先输入一个数字表示二进制的位数,在程序中有变量记录二进制的位数。再根据提示输入一个二进制数。其转换的主要思想是 二进制数的每四位代表十六进制的,通过移位来逐一将四个二进制位数的和转换成十六进制数保存在一个寄存器中,然后再继续按照每四位一求和的方法保存十六进制数的每一位,直到二进制数的所有位计算完毕,当对四位二进制数相加完毕后,将保存和的寄存器清零,采用相对寻址改变十六进制数每一位存放的位置。其中还会对十六进制每一位上的数字进行判断,若是大于9,则转换成相应的字母,最后采用相对寻址的方式将十六进制的每一位依次输出。显示完毕后,跳转到主菜单。 4、十六进制向二进制的转换。当用户选择编号d,便选择了这一个子功能。通过判断标识符,程序跳转到标识符所在的位置。根据提示输入一个十六进制数,此时会进行判断,判断输入的字符串是否符合十六进制数的要求,若是输入错误,则提示输入错误,重新输入,直到输入正确为止。其转换的主要思想是通过转换成十进制,然后将十进制数转换成二进制,在十六进制转换成十进制中,按权值展开再相加的思想,在十进制转换成二进制的中,主要是采用连除的方法,将每一次的余数保存在堆栈中,直到商为零。最后出栈,根据栈的先进后出的原则,出栈的顺序就是转换后的二进制数的顺序。将转换后的二进制数输出后,跳转到主菜单。 5、十六进制向十进制的转换。当用户选择编号e,便选择了这一个子功能。通过判断标识符,程序跳转到标识符所在的位置。根据提示输入一个十六进制数,此时会进行判断,若是输入字符串不符合十六进制数的要求,则提示输入错误,重新输入,直到输入正确为止。十六进制数转换成十进制的主要思想是,按权值展开再相加。首先是将输入的字符转换成相应的数字,通过设置相应的变量,在最低位上的权值是1,然后依次是16,256依次进行累乘,直到十六进制数位数全部循环完毕,将每一位所得的数保存在寄存器中,每进行一次就实现一次求和运算。最后将转换成的十进制数输出,跳转到主菜单。 6、退出。当用户选择编号q,便选择了退出。通过判断标识符,程序跳转到标识符所在的位置,实现退出。四、 程序流程图 开 始主菜单,用户选择子功能输入有误,重新输入其他退出abcdeq输入十六进制数输入二进制数输入小字母写输入大写字母输入错误输入错误输入错误判断输入是否合法输入错误判断输入是否合法N判断输入是否合法判断输入是否合法NNNY转换十进制YYY转换二进制数转换转换转换d判断子功能结 束输出输出输出输出输出e附图:图1:编译显示的主菜单图2:各个子功能显示五、 程序源代码include io32.inc .data m1 byte ' 代码转换系统 ',13,10,0 ;菜单 m2 byte '-',13,10,0 ;分割线 m3 byte ' 编号 操作 ',13,10,0 ma byte ' a 实现大写字母向小写字母的转换',13,10,0 mb byte ' b 实现小写字母向大写字母的转换',13,10,0 mc byte ' c 实现二进制向十六进制数的转换',13,10,0 md byte ' d 实现十六进制向二进制数的转换',13,10,0 me byte ' e 实现十六进制向十进制数的转换',13,10,0 mq byte ' q 退出',13,10,0 m_err byte ' 输入错误,请重新输入',13,10,0 m_meau byte '请输入菜单中的编号: ',0 m_inputs byte '请输入一个小写字母: ',0 m_inputl byte '请输入一个大写字母: ',0 m_outputl byte '对应的小写字母: ',0 m_outputs byte '对应的大写字母: ',0 m_input1 byte '请输入二进制位数: ',0 m_input11 byte '请输入二进制数: ',0 m_output1 byte '转换后的十六进制数: ',0 m_output2 byte '转换后的二进制数: ',0 m_input3 byte '请输入一个十六进制数: ',0 m_output3 byte '转换后的十进制数: ',0 array byte 8 dup (0) ;用字符串数组保存十六进制数 sum dword ? ;十进制数变量 len byte ? ;字符串数组的长度 m byte ? array1 byte 100 dup (0) ;定义一个数组用来保存初始二进制数 array2 byte 100 dup (0) ;用来保存转换后的十六进制数 n dword ? k dword ? j dword ? .codestart: mov eax,offset m1 ;显示菜单中的内容 call dispmsg mov eax,offset m2 call dispmsg mov eax,offset m3 call dispmsg mov eax,offset ma call dispmsg mov eax,offset mb call dispmsg mov eax,offset mc call dispmsg mov eax,offset md call dispmsg mov eax,offset me call dispmsg mov eax,offset mq call dispmsgmeau: mov eax,offset m_meau call dispmsg ;提示输入相应的菜单编号 call readc ;输入对应的编号 call dispcrlf ;换行 cmp al,'a' ;判断输入 jz a ;若输入a,则跳转到标识符a cmp al,'b' jz b ;若输入b,则跳转到标识符b cmp al,'c' jz cc ;若输入c,则跳转到标识符cc cmp al,'d' jz e ;若输入d,则跳转到标识符e cmp al,'e' jz e ;若输入e,则跳转到标识符e cmp al,'q' jz q ;若输入q,则跳转到标识符q mov eax,offset m_err call dispmsg ;输入错误,提示错误的信息 jmp meau ;大写字母向小写字母的转换returna: mov eax,offset m_err call dispmsga: mov eax,offset m_inputl call dispmsg ;提示输入一个大写的字母 call readc ;获得字母 mov bl,al ;将输入的内容存储到bl中 call dispcrlf ;换行 cmp al,'A' ;判断输入的字母是否合法 jb returna ;如果比'A'小,则跳转到returna标识符 cmp al,'Z' ja returna ;如果比'Z'大,则跳转到returna标识符 call dispc ;显示字母 mov eax,offset m_outputl call dispmsg ;输入正确,则提示输出相应的小写字母 add bl,20h ;实现大写向小写的转换 mov al,bl call dispc ;显示转换后的字母 call dispcrlf ;换行 jmp meau ;小写字母向大写字母的转换returnb: mov eax,offset m_err call dispmsgb: mov eax,offset m_inputs call dispmsg ;提示输入一个小写字母 call readc ;获得字母 mov bl,al ;将输入的内容存储到bl中 call dispcrlf cmp al,'a' ;判断输入合法性 jb returnb ;如果比a小,则跳转到returnb标识符 cmp al,'z' ja returnb ;如果比z大,则跳转到returnb标识符 call dispc ;显示字母 mov eax,offset m_outputs call dispmsg ;提示输出相应的大写字母 sub bl,20h ;实现小写到大写字母的转换 mov al,bl call dispc ;将转换的字母输出 call dispcrlf ;换行 jmp meau ;二进制向十六进制转换cc: mov eax,offset m_input1 call dispmsg call readuid ;输入二进制数的位数 mov j,eax ;保存二进制位数 mov eax,offset m_input11 ;提示输入二进制数 call dispmsg call dispcrlf mov ecx,0 ;清零,计数器c1: call readuid mov array1ecx,al ;一位一位的输入 inc ecx cmp ecx,j jb c1 ;低于位数,继续输入 mov ecx,j dec ecx mov eax,1 xor ebx,ebx ;记录移动的位数 xor edx,edx ;表示四个二进制位的和 xor esi,esi ;保存十六进制当前的位置c2: mov n,0 ;n作为二进制位数是否已达4位的一个标志 mov k,0 ;k作为数值是否已经结束的一个标志 cmp array1ecx,1 jnz c11 ;判断二进制数的某一位是否为1 mov eax,1 cmp ebx,1 jnz c3 ;判断数据所在的位数,不相等,转向c3 shl eax,1 ;逻辑左移 jmp c5c3: cmp ebx,2 jnz c4 ;根据比较来确定移动的位数 shl eax,2 ;逻辑左移 jmp c5c4: cmp ebx,3 jnz c5 ;根据比较来判断移动的位数 shl eax,3 ;逻辑左移c5: add edx,eax ;保存和c11: cmp ebx,3 ;判断二进制数是否已经有四位 jnz c12 mov n,1c12: cmp ecx,0 ;判断数值是否已经全部计算完毕 jnz c13 mov k,1c13: mov edi,n or edi,k ;保存n或者k的值 cmp edi,1 jnz c16 cmp edx,9 jna c14 sub edx,10 ;edx大于9 add edx,'A' ;转换成相应的字母 mov array2esi,dl ;将十六进制数保存至数组 jmp c15c14: add edx,'0' mov array2esi,dl ;edx大于等于0小于等于9c15: inc esi ;改变当前十六进制数所在位置 xor edx,edx ;清零以便下一次运用 mov ebx,-1c16: inc ebx dec ecx cmp ecx,0 jnl c2 ;小于0,退出循环 mov eax,offset m_output1 call dispmsg mov ecx,esi ;16进制数的位数 dec ecxccc: mov al,array2ecx call dispc ;输出每一个十六进制数 dec ecx cmp ecx,0 ;输出转换后的数据 jnl ccc call dispcrlf jmp meau ;返回主菜单 ;十六进制向二进制的转换d: mov eax,20 push eax ;将20作为一个判断标识 mov eax,sum ;将十进制数存入eax中 jmp d1 d1: mov edx,0 mov ebx,2 ;除数2 div ebx mov ecx,eax ;保存商 mov eax,edx push eax ;将余数压入栈 mov eax,ecx cmp eax,0 ;判断商是否为0 jz d2 jmp d1d2: mov ecx,eax ;暂存 mov eax,offset m_output2 call dispmsg mov eax,ecx jmp d3d3: pop eax ;出栈 cmp eax,20 jz d4 ;判断是否出栈完毕 call dispsid jmp d3d4: call dispcrlf jmp meau ;返回主菜单 ;十六进制向十进制的转换e: mov m,al mov eax,offset m_input3 call dispmsg mov eax,offset array call readmsg mov len,al ;获得字符串长度 xor ecx,ecx ;异或清零 mov cl,len ;计数 dec cl ;自减1 xor eax,eax mov edx,1 ;初始权值again: cmp arrayecx,'A' jl shiliu_shi1 ;小于A,转向shiliu_shi1 cmp arrayecx,'F' jg shiliu_shi1 ;大于Z,转向shiliu_shi1 xor ebx,ebx mov bl,arrayecx ;相对寻址 sub bl,55 ;转换成相应的数字 imul ebx,edx add eax,ebx imul edx,16 ;改变权值 jmp shiliu_shi3shiliu_shi1: cmp arrayecx,'0' jl shiliu_shi2 ;小于0,转向shiliu_shi2 cmp arrayecx,'9' jg shiliu_shi2 ;大于9,转向shiliu_shi2 xor ebx,ebx ;临时寄存 mov bl,arrayecx sub bl,'0' ;转换成相应的数字 imul ebx,edx add eax,ebx imul edx,16 ;改变权值 jmp shiliu_shi3 shiliu_shi2: mov eax,offset m_err call dispmsg ;提示输入错误 jmp eshiliu_shi3: dec ecx ;自减 cmp ecx,0 jnl again ;不小于0,转向again mov sum,eax cmp m,'d' ;判断选择的功能 jz d ;为d,继续进行转换成二进制 cmp m,'e' jz ee ;为e,直接输出ee: mov eax,offset m_output3 call dispmsg mov eax,sum ;数据输出 call dispuid call dispcrlf jmp meau ;返回主菜单q: jmp done ;退出done: exit 0end start六、 设计过程中遇到的问题及解决办法 在代码转换程序设计的过程中,字母转换基本上没有什么问题,主要困难之处在于二进制,十六进制,十进制之间的互换。 1、二进制转换成十六进制。刚开始的时候是计划采用每四个二进制位转换成一个十六进制的方法,然而其二进制的位数又不能简单的确定,因此最后采用先输入二进制的位数,再输入二进制数的方法,以便于控制在转换过程中需要移动的位数。另外,在转换成十六进制的过程中,面临着超过9就必须转换成相应的字母的问题,最后通过查阅资料,采用了先将其转换成相应的assic码,再进行存储相关的十六进制数。最后通过相对寻址,将十六进制数的每一位输出来。 2、十六进制转换成十进制。主要是采用按权展开相加的方法,但是每一位的权值又不一样,这就使得数值难以控制,最后采用每进行一位的转换,利用寄存器将权值乘以16,最后将数字相加。 3、十六进制转换成二进制。起初是准备采用按照每四位相当于4位二进制数的方法进行转换,比较麻烦。由于有一个将十六进制转换成十进制数的功能,而且将十进制数转换成二进制数十分的方便简单,因此最后采用先将十六进制数转换成十进制数,再将十进制数转换成二进制数的方法来实现。七、 设计心得 通过这次的课程设计,让我对汇编有了更进一步的认识,加强了我用汇编语言编程的能力。 在这次程序设计的过程中,让我进一步了解到了汇编语言的一些基本的指令,以及各个寄存器的功能及使用的方法。在设计的过程中不断地修改,改进,增强了自己分析问题解决问题的能力;在不断地调试过程中,不断的发现问题,解决问题,通过查资料,翻阅相关的书籍,以及向同学们请教,来逐一的解决各个问题。同时也更深的了解到了寄存器,存储器等的工作原理以及需要注意的一些问题。 此次课程设计收获颇多,不仅仅是体会到了分析问题,想出解决方案的重要性,更是在编写代码转换这一程序的过程中,了解到每一个系统都是由许多的子功能组成的,我们在编写的过程中,可以先把每一个子功能分开编写,这样更容易发现错误,尽快的想出解决的方法,在将每一个子功能编写完毕后,逐一的将它们嵌入到主菜单中去,实现一个完整的系统。 另外,在每一个子功能的编写过程中,需要十分的注意到各个变量名的统一化,以便于将其嵌入到主菜单中去,在编写标识符的名字的时候,尽量要做到看名字知其含义,使程序的可读性进一步增高。 在编写代码转换程序的过程中,更是体会到了科学的严谨性,每一个小小的错误都不容忽视,再细小的地方都需要注意,否则将会导致程序的错误。不管在做什么,都需要十分的认真和谨慎,将每一步都做到最好。 当设计一步步接近成功,每一个子功能调试正确,都会让自己感到很高兴,从中体会到了编程的乐趣,让自己更有信心,增强了对汇编语言程序设计的兴趣。专心-专注-专业