当前位置:文档之家› 代码转换

代码转换

前言

代码转换程序主要是字母间的转换和数制之间的转换。字母转换主要是字母大小写转换,进制转换是二进制、十进制、十六进制之间的互换。程序首先给了一个选择需要进行的转换的菜单,用户根据界面信息选择功能。通过这种转换中数据的流向能够更好的理解计算机的一些基本原理,如计算机数据的存储形式和一些基本的DOS功能调用的基本方法与注意事项。

中文摘要

代码转换程序主要是字母间的转换和数制之间的转换。字母转换主要是字母大小写转换,进制转换是二进制、十进制、十六进制之间的互换。程序首先给了一个选择需要进行的转换的菜单,用户根据界面信息选择功能。通过这种转换中数据的流向能够更好的理解计算机的一些基本原理,如计算机数据的存储形式和一些基本的DOS功能调用的基本方法与注意事项。

关键字:大小写字母,二进制,十进制,十六进制,数据

目录

一设计目的 (1)

1.1.系统总体分析 (1)

1.2主模块框图及说明 (1)

二详细设计 (3)

2.1.主模块及子模块说明 (3)

三程序调试 (4)

3.1.运行界面分析 (4)

3.2.算法分析 (6)

3.3.调试过程及分析 (7)

四设计总结 (8)

4.1.设计体会 (8)

4.2.系统改进 (8)

参考文献 (9)

致谢 (10)

程序清单 (11)

1、设计目的

1、实现大小写字母之间的转换:输入的字符串中,不是字母的字符不改变;大写字母改成小写字母时,若是大写字母则不改变;同样,小写字母改成大写字母时,若是小写字母则不改变

2、二进制和十六进制数之间的转换:输入一个二进制数(或十六进制数),用十六进制数(或二进制数)表示输出。最多能把十六位二进制数(或四位十六进制数)用四位十六进制数(或十六位二进制数)表示输出;小于十六位(或四位)时按回车结束并输出

3、十进制数和十六进制数之间的转换:输入一个十进制数(或十六进制数),用十六进制数(或十进制数)表示输出。最大能把十进制数65535(或十六进制数FFFF)转换成十六进制数FFFF(或十进制数65535)表示输出;小于65535(或FFFF)时按回车结束并输出

4.二进制数和十进制数之间的转换:输入一个十进制数(或二进制数),用二进制数(或十进制数表示输出)。最大能把十进制数65535(或十六位二进制数),用二进制数(或十进制输出)。当输入的数值小于65535(或16位二进制数时)按回车结束并输出。

1.1 系统总体分析

程序首先会显示主界面。然后根据用户的不同选择调用不同的模块,实现不同的功能。

1.大小写字母转换功能,是通过调用子函数input实现对字符串的输入,然

后调用宏gaixie来实现对大小写的转换,其中宏是通过参数的传递来

确定是小写转换成大写,还是大写转换成小写的。从而决定是对操作

数进行加或减20H。

2.数制之间的转换主要指通过六大模块来完成的。其中有三个模块是分别

是二进制、十进制、十六进制的输入,并存储到BX中。类外三个模块

分别是将BX中的数转换成二进制、十进制、十六进制的输出。这样做

的好处是可以只写将程序尽可能的简化,将前三个模块与后三个模块

进行组合就可以完成所需要的进制转换。

1.2主模块框图及说明

程序首先显示主界面,然后用户输入1-9选择不同的功能,

则跳转到不同的模块,执行后在跳转到主模块,若是其他字符,则显示出错信息,并返回主模块。如图2-1为主模块的逻辑图

图2-1 主模块的逻辑图

2、详细设计

2.1 主模块及子模块说明

主模块:在屏幕上显示程序的主要功能并有用户选择,然后根据用户的选择调用相应的功能模块。

HEXIBIN:输入一个十六进制数(不超过4位),并存放在BX中

INBIN:输入二进制数(不超过16位),并存放在BX中

DECIBIN:输入一个十进制数(不超过65535),并存放在BX中

BINIHEX:把BX中的数转换成十六进制并输出

BINIDEC:用来把BX数转换到十进制并

PRINT:用来把BX中的数转换成二进制并输出

INPUT:字符串的输入,并存储

GAIXIE:把字符串转换成大写或小写,然后输出

CRLF:换行

3、程序调试3.1 运行界面分析

运行程序得如图4-1主界面

图4-1 主界面

选择1,大写字母转小写字母如图4-2

图4-2 大写字母转小写字母选择2,小写字母转大写字母如图4-3

图4-3 小写字母转大写字母选择3,十六进制到二进制的转换,如图4-4

图4-4 十六进制转二进制选择4,二进制到十六进制的转换,如图4-5

图4-5 二进制转十六进制选择5,十六进制到十进制的转换,如图4-6

图4-6 十六进制转十进制

选择6,十进制到十六进制的转换,如图4-7

图4-7 十进制转十六进制

选择7,二进制到十进制的转换,如图4-8

图4-8 二进制转十进制

选择8,十进制到二进制的转换,如图4-9

图4-9 十进制转二进制

选择9则退出,选择其他输入,如输入q,如图4-10

图4-10 错误输入

3.2算法的分析

代码转换器主要是由两部分组成:大小写字母转换和数制转换。

大小写字母转换就是在其原来的ASCII码的基础上或加或减20H就可得到。

数值转换是二进制、十进制、十六进制之间的转换。通过调用不同的函数避免了数值之间的转换。首先是三个输如模块,对于输入的字符如果是0-10之间的就减去30H,得到其代表的数的含义,A-F之间的就减去37H,a-f之间的就

减去57H,得到其代表的数的含义,让后乘以权值相加存于BX即可。然后是三个输出模块,因为BX中存的本就是二进制数,所以直接移位输出就可得到二进制数。十六进制数是每四位二进制数转换成一位十六进制数即可。十进制数相对复杂,将BX中的数转换成十进制数输出,就是将BX中的数每次分别处以10000,1000,100,10,1将其所得到的商输出,而其余数存入BX中进入下一轮循环。这样输出就是要得到的十进制数。

3.3 调试过程及分析

在进行调试的过程中遇到的问题层出不穷,但大多是因为一些粗心的错误。刚开始遇到最多的问题便是程序在编译时没有任何错误,链接的按钮仍然是灰色的不能够链接,茫然不知所措。上网查找资料却找不到任何相应的情况。于是就不用学校机房里的MASM,换了另外一款编译器(Masm for Windows 集成实验环境 2009.2),在进行编译时提示出错“Invalid character in the file”,在错误信息表中查得是文中使用了无效字符,多数情况下是使用了中文的标点符号。根据这款编译器中代码颜色的不同很快就发现了是在写注释的时候“;”使用错误了。另外一个让我记忆犹新的问题是所有的子函数都是正确的,但是在将所有的模块进行组合时出了个错“relative jump out of range by 0001h bytes”,感觉很郁闷,在编译器给的信息表中也没有查到为什么。最后在网上查到答案即:8086中的条件跳转指令的跳转范围是-126~129(相对于该指令的字节偏移量),不能超出这个范围。原代码: CMP AL,'2'

JZ STOB

更改为:CMP AL,’2’

JZ STOB1

STOB1:JMP STOB

如此就搞定了。当然还有一些平时不会注意到的问题,比如使用INT指令会改

变AL的值,这些微不足道的地方却恰恰是最容易忽略的地方。

4、设计总结

4.1 设计体会

经过一个星期的工作,才把课程设计完成。经过这次课程设计,我加深了对汇编语言的理解,也对上课时所说的语法有了深刻的认识。

相对于以前学习的高级语言,对汇编语言的第一印象是很酷,因为它很抽象。怀着崇拜的心情学着汇编语言,虽然枯燥,但是每当完成一个很简单的程序就会感到非常的有成就感。

当我刚开始选择这个题目是因为课本上有一个相近的代码转换,所以感觉这个题目应该很好写。可是等到真正动手的时候就感到了困难。首先是对字符串的输入输出的处理,解决不了就改成了字母大小写转换是每次只输入一个字母,然后根据其大小写转换,如大写就转换成小写,否则反之。然而在随后的进制转换中用遇到了同样的问题,发现这是一个不能不解决的问题,随后查阅了资料才解决。随后实在数值转换过程中对模块的设计上又出现了问题。最初的构想是设计六个模块分别对应相应的数值转换功能。可是在三个写好以后发现了下面要写的代码有很多重复的地方,于是就把这些重复的代码定义成了子函数来使用然后发现将程序按照输入、输出的不同来分模块,以BX作为连接,比原来的程序更为简洁,逻辑上也更加清楚,有种豁然开朗的感觉。在改进程序的过程中感到非常有成就感。

在编写代码的过程中让我充分感受到了不同编程语言之间的差别。对与高级语言来说或许是很简单的一个程序或者只需要调用已有的函数库,可是对于汇编来说却要写上几十行甚至更多的代码。可是更加深刻的了解了寄存器、存储器之间的数据流向,因为每个考虑不周都会导致一大堆的错误出现,常常令人感到一种无力感,想要放弃。

当程序一步步接近完成,看着子函数一个个都运行成功,再组合到一起,那种喜悦是无与伦比,之前所受到的苦楚又是那么的微不足道。更怎强了我对汇编语言的兴趣。

4.2 系统改进

此程序的健壮性不够,在数值转换的过程中,当输入被换算的数值时,如果数值是正确的则能够正确的处理,当不正确的时候都输出的是0。数值转换的数值范围是0FFFFh,这是BX中存储的最大范围了,应该可以将其改进的更大一些。

参考文献

1 王爽.汇编语言(第二版).清华大学出版社, 2008。

2 沈美明,温冬婵.IBM-PC汇编语言程序设计(第二版).清华大学出版社, 2001。

3[美]Kip R.Irvine著,温玉洁,等译.Intel汇编语言程序设计(第五版).电子工业出版社, 2007。

4 钱晓捷.汇编语言程序设计(第二版). 电子工业出版社, 2003。

5 罗云彬.Windows环境下32位汇编语言程序设计(第二版).电子工业出版社, 2006。

6Windows API函数参考手册.人民邮电出版社, 2002。

致谢

历时一周的时间终于将这个课程设计做完,在设计的过程中遇到了无数的困难和障碍,都在同学和老师的帮助下度过了。尤其要强烈感谢我的课设指导老师刘树群老师,他对我进行了无私的指导和帮助,不厌其烦的帮助进行程序的修改和改进。另外,在校图书馆查找资料的时候,图书馆的老师也给我提供了很多方面的支持与帮助。在此向帮助和指导过我的各位老师表示最中心的感谢!引用了数位学者的研究文献,如果没有各位学者的研究成果的帮助和启发,我将很难完成这次的课程设计。感谢我的同学和朋友,在我做课程设计的过程中给予了我很多素材。

程序清单

CODE SEGMENT

ASSUME CS:CODE,DS:DATA

START:MOV AX,DATA

MOV DS,AX

MOV DX,OFFSET BUF ;输出选择主界面

MOV AH,9 ;调用9号中断功能

INT 21H

MOV AH,1 ;输入要选择的操作

INT 21H

CMP AL,'1' ;把AL中内容跟1比较

JZ BTOS ;相等则跳转到

CMP AL,'2'

JZ STOB1

CMP AL,'3'

JZ HTOB

CMP AL,'4'

JZ BTOH

CMP AL,'5'

JZ HTOD

CMP AL,'6'

JZ DTOH

CMP AL,'7'

JZ BTOD

CMP AL,'8'

JZ DTOB

CMP AL,'9'

JZ EXIT

LEA DX,BUF3 ;把BUF3的首地址给DX

MOV AH,9

INT 21H

CALL CRLF ;调用子程序CALL

JMP START ;返回,重新选择

EXIT:MOV AH,4CH ;退出

3.2.2 HEXIBIN

首先将BX清零作为输入数的存储,DX清零记为输入数的位数控制输入循环。通过对每一个输入输出判断其为小写字母或大写字母或数字,减去不同的数值,得到其代表的数值大小。然后将BX中的数值乘以16再与其相加存于BX 中,同时DX加1,入DX不大于4,则进入下一轮跳转,否则就结束。HEXIBIN PROC NEAR

MOV BX,0 ;把BX清零

MOV DX,0 ;作为输入四位的记数器

INHEX:CMP DX,4 ;把DX跟4比较

JNB HEXEND ;大于则跳转,子程序结束

MOV AH,1 ;输入数据

INT 21H

CMP AL,1BH ;遇到Esc则退出

JZ HEXEND

SUB AL,30H ;判断是否数字或字母?否则跳出

JL HEXEND

CMP AL,10 ;判断是否数字

JL ADD_TO ;是则存放BX中

SUB AL,7 ;把AL内容减7转为字母

CMP AL,10 ;判断是否小写字母(a~f)

JL HEXEND

CMP AL,16

JL ADD_TO ;小于则跳转

SUB AL,20H ;判断是否大写字母(A~F)

CMP AL,10

JL HEXEND

CMP AL,16

JGE HEXEND

ADD_TO:MOV CL,4 ;作为循环条件

SHL BX,CL ;BX乘以16

MOV AH,0

ADD BX,AX ;两数相加

INC DX ;DX加1

JMP INHEX

HEXEND:RET

HEXIBIN ENDP

3.2.3 INBIN

程序同上一个模块基本相同。首先将BX清零作为输入数的存储,CX清零记为输入数的位数控制输入循环。通过对每一个输入数字,减去30H,得到其代表的数值大小。然后将BX中的数值乘以2再与其相加存于BX中,同时CX加1,入CX不大于16,则进入下一轮跳转,否则就结束。

INBIN PROC NEAR ;输入十六二进制数

MOV BX,0

MOV CX,0

PUTIN:CMP CX,16

JNB EXIT6

MOV AH,1

INT 21H

CMP AL,1BH

JZ EXIT6

SUB AL,30H

JL EXIT6

CMP AL,1

JG EXIT6

CBW

INC CX

XCHG AX,BX

MOV DX,2

MUL DX

XCHG AX,BX

ADD BX,AX

JMP PUTIN

EXIT6:RET

INBIN ENDP

3.2.4 DECIBIN

程序同上一个模块基本相同。首先将BX清零作为输入数的存储,CX清零记为输入数的位数控制输入循环。通过对每一个输入数字,减去30H,得到其代表的数值大小。然后将BX中的数值乘以10再与其相加存于BX中,同时CX加1,入CX不大于5,则进入下一轮跳转,否则就结束。

DECIBIN PROC NEAR

MOV BX,0

MOV CX,0

NEWCHAR:CMP CX,5

JNB EXIT4

MOV AH,1

INT 21H

CMP AL,1BH

JZ EXIT4

SUB AL,30H

JL EXIT4

CMP AL,9

JG EXIT4

CBW

INC CX

XCHG AX,BX

MOV DX,10

MUL DX

XCHG AX,BX

ADD BX,AX

JMP NEWCHAR

EXIT4:RET

DECIBIN ENDP

3,2,5 BINIHEX

将BX中的数转换成十六进制数输出就是每次取出四位算出其数值,然后转换成相应的ASCII码输出。

BINIHEX PROC NEAR ;把数转换成十六进制输出

MOV CH,4

ROTATE:MOV CL,4

ROL BX,CL ;把BX中高四位移到低四位,放到AL中

MOV AL,BL

AND AL,0FH

ADD AL,30H

CMP AL,3AH ;判断是否为数字

JL PRINTIT

ADD AL,7

PRINTIT:MOV DL,AL

MOV AH,2

INT 21H

DEC CH

JNZ ROTATE

RET

BINIHEX ENDP

3.2.6 BINIDEC

将BX中的数转换成十进制数输出,就是将BX中的数每次分别处以10000,1000,100,10,1将其所得到的商输出,而其余数存入BX中进入下一轮循环。这样输出就是要得到的十进制数。

BINIDEC PROC NEAR

MOV CX,10000 ;把10000给CX,作为万位的权

CALL DEC_DIV ;调用除权子程序

MOV CX,1000

CALL DEC_DIV

MOV CX,100

CALL DEC_DIV

MOV CX,10

CALL DEC_DIV

MOV CX,1

CALL DEC_DIV

RET

BINIDEC ENDP

DEC_DIV PROC NEAR ;除以各位十进制的权

MOV AX,BX ;把BX内容给AX

MOV DX,0 ;DX清零

DIV CX

MOV BX,DX

MOV DL,AL

ADD DL,30H ;转换为ASSII

MOV AH,2

INT 21H

RET

DEC_DIV ENDP

3.2.7 PRINT

将BX中的数转换成二进制:因为BX中原本就是按照二进制存储的,所以只需每次左移,将所得到的数加30h得到其ASCII 码然后输出即可。

PRINT PROC NEAR ;把BX中的十六进制数转换成二进制MOV CX,16D ;记数

ROT: SHL BX,1D ;每移一位最高位变为CF

JC SET ;CF为1则跳到SET,否则输出0

MOV DL,30H

MOV AH,2

INT 21H

DEC CX

JNZ ROT

RET

3.2.8 INPUT

输入字符串:通过10号功能调用,将所输入的字符串输入到缓冲区,缓冲区首=DS:DX

INPUT PROC NEAR ;输入字符串

MOV DX,0 ;DX清零

MOV DX,OFFSET BUF1

MOV AH,10

INT 21H

LEA DX,BF

MOV AH,9

INT 21H

LEA SI,BUF1+2

MOV BL,[SI-1] ;把输入的字符个数给BL

MOV BH,0 ;BH清零

MOV BYTE PTR [BX+SI+1],'$' ;把$作为字符串结束字符

LEA DX,BUF1+2

MOV AH,9

INT 21H

RET ;返回

INPUT ENDP

3.2.9 GAIXIE

大小写字母的转换只是对其加上或者减去20H即可。P3、P4分别对应的是‘a’、‘z’或者‘A’、‘Z’,P6对应的是ADD或者SUB。

GAIXIE MACRO P1,P2,P3,P4,P5,P6 ;来判定字母?

P2: CMP BYTE PTR [SI],P3

JB P5 ;小于跳转

CMP BYTE PTR [SI],P4

JNB P5

CMP BYTE PTR [SI],'$' ;到$则结束

JZ P6

P1 BYTE PTR [SI],20H

P5: INC SI

LOOP P2

P6: LEA DX,BUF8

MOV AH,9

INT 21H

LEA DX,BUF1+2 ;输出改写后的字母

MOV AH,9 ;调用9号中断功能,输出字符串

INT 21H

LEA DX,BF ;把BF首地址给CX

MOV AH,9 ;调用9号中断功能

INT 21H

JMP START ;返回

相关主题
文本预览
相关文档 最新文档