微机原理实验 从键盘输入数据并显示


前言

微机原理的学习基本大部分内容都和汇编语言相关,以下是笔者第二次实验的相关实验内容。

一、实验内容

编写程序,将键盘接收到的四位十六进制数转换为等值的二进制数,再显示在屏幕上。若输入的不是0-F间的数字,则显示错误信息,并要求重新输入。

二、实验原理

在进行代码书写前我们首先需要知道,在汇编语言中INT 21H的调用是一个非常重要的命令,课程或者实验中经常需要用到其中的一些指令

而对于本门课程来说,编号01H(单字输入),02H(单字输出),09H(字符串输出),0AH(字符串输入)和4CH(程序结束)是几条比较常用的指令。在该程序中,调用的是0AH号功能进行输入。当然,题目要求的是接收四位,因此采用01H号功能是常规的选择,笔者这里是进行了一些拓展。

	MOV AH,0AH
    INT 21H
    LEA SI,BUFFER1				;输入字符串
    INC SI
    MOV CL,[SI]					;BUFFER1内第二个数为长度,控制循环
    INC SI						;此时SI指向了字符串的首地址



接下来我们需要做的便是进行数值判断,如果是0-9之间的数字,无需处理,如果是大写A-F或者小写的a-f,进行统一的大小写转换,如果是其他的数值则抛出错误。

L1:
	MOV BL,20H
    OR [SI],BL					;将字符变成小写字母(设置第六位为1)
	MOV AL,[SI]
	CMP AL,'9'					;判断字符是否大于9
	JA OVER_OCT
	CMP AL,'0'					;判断字符是否小于0
	JB INPUT_ERROR
	JMP	NORMAL					;在0~9之间,不进行其他操作
	
OVER_OCT:
	CMP AL,'a'					;判断字符是否小于a
	JB INPUT_ERROR
	CMP AL,'f'					;判断字符是否大于f
	JA INPUT_ERROR	



在完成输入之后我们则需要进行数值处理,这是本次实验中比较关键的一个部分。有些代码可能采用移位的操作将单个数字转换成二进制数。笔者这里采用的是连除法,直接用进制转换的公式进行推导。
每次处理一个数将它除以二,所得的余数存于一个数组内,商继续转到下一次的除法中,直到四次除完。
譬如十六进制中的E,转换为十进制数字是14。14÷2=7余0,7÷2=3余1,3÷2=1余1,1÷2=0余1,我们只需要将这些余数存入数组,最后倒着输出即可得到E对应的二进制数1110。将数组显示出来后,对接下来的数字进行相同的操作即可。

SHOW PROC
	MOV BL,[SI]
	CMP BL,60H
	JB NORMAL_OCT
	MOV BL,7H
	SUB [SI],BL					;根据所用的转换方法推导可得a~f需要减7H再减去60H
NORMAL_OCT:	
	MOV AL,[SI]
	MOV SHU,AL					;保护AL
	SUB AL,30H
	MOV DI,OFFSET EMP
	MOV CX,4					;循环4次,除以4次2

D1:
	MOV AH,0
	MOV AL,SHU					;被除数放AX里
	DIV TWO						;余数在AH,商在AL
	MOV SHU,AL					;商留着放下一次除法循环里
	ADD AH,30H
	MOV DS:[DI],AH				;余数加30H放在EMP里面
	INC DI
	LOOP D1
	
	MOV CX,4					;单个数的BCD码是四位
D2:
	DEC DI						;倒着输出EMP里的数
	MOV DL,DS:[DI]
	MOV AH,02H
	INT 21H
	LOOP D2
	RET
SHOW ENDP						

最后我们将所有代码片段结合起来。

三、实验代码

DATAS SEGMENT
    BUFFER1 DB 101,?,101 DUP (?)			    ;第一个101表示最大长度为101个字符,?占用的那个字节在调用结束后会被放入实际输入的字符个数
												;101 DUP(?)表示开辟101字节单元,存放输入的字符的ASCII码。
	MES1 DB 0AH,0DH,'The code is: $'			;0A ASCII码表示换行,0D ASCII码表示回车
    MES2 DB 0AH,0DH,'$'							;换行,清晰程序
    MES3 DB 'Input your number: $'
    MES4 DB 0AH,0DH,'Input error,please try again!',0AH,0DH,'$'
    SHU DB ?
    EMP DB 4 DUP (?)							;在此处理BCD码
    TWO DB 2									;定义TWO=2
DATAS ENDS

STACKS SEGMENT
	DW 256 DUP (?)								;涉及到进入子程序的断点保护,需要入栈出栈
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
	;初始化
    MOV AX,DATAS
    MOV DS,AX 
    MOV	AX,STACKS
	MOV	SS,AX
    MOV DX,OFFSET MES3
    MOV AH,09H
    INT 21H
    
    ;输入到缓冲区
    LEA DX,BUFFER1
    MOV AH,0AH
    INT 21H
    LEA SI,BUFFER1				;输入字符串
    INC SI
    MOV CL,[SI]					;BUFFER1内第二个数为长度,控制循环
    INC SI						;此时SI指向了字符串的首地址
    MOV DX,OFFSET MES1
    MOV AH,09H
    INT 21H
    
    ;开始逐个处理输入的字符串
L1:
	MOV BL,20H
    OR [SI],BL					;将字符变成小写字母(设置第六位为1)
	MOV AL,[SI]
	CMP AL,'9'					;判断字符是否大于9
	JA OVER_OCT
	CMP AL,'0'					;判断字符是否小于0
	JB INPUT_ERROR
	JMP	NORMAL					;在0~9之间,不进行其他操作
	
OVER_OCT:
	CMP AL,'a'					;判断字符是否小于a
	JB INPUT_ERROR
	CMP AL,'f'					;判断字符是否大于f
	JA INPUT_ERROR	
	
NORMAL:	
	PUSH CX						;进入子程序前保护CX
	CALL SHOW
	POP CX
	MOV DL,20H					;输出空格
	MOV AH,02H
	INT 21H
	INC SI
	LOOP L1
    
    MOV DX,OFFSET MES2
    MOV AH,09H
    INT 21H
    JMP DONE

DONE:
    MOV AH,4CH					;程序在此结束
    INT 21H

INPUT_ERROR:
	MOV DX,OFFSET MES4			;错误字符,重新跳转到开头输入
    MOV AH,09H
    INT 21H
    JMP START


SHOW PROC
	MOV BL,[SI]
	CMP BL,60H
	JB NORMAL_OCT
	MOV BL,7H
	SUB [SI],BL					;根据所用的转换方法推导可得a~f需要减7H再减去60H
NORMAL_OCT:	
	MOV AL,[SI]
	MOV SHU,AL					;保护AL
	SUB AL,30H
	MOV DI,OFFSET EMP
	MOV CX,4					;循环4次,除以4次2

D1:
	MOV AH,0
	MOV AL,SHU					;被除数放AX里
	DIV TWO						;余数在AH,商在AL
	MOV SHU,AL					;商留着放下一次除法循环里
	ADD AH,30H
	MOV DS:[DI],AH				;余数加30H放在EMP里面
	INC DI
	LOOP D1
	
	MOV CX,4					;单个数的BCD码是四位
D2:
	DEC DI						;倒着输出EMP里的数
	MOV DL,DS:[DI]
	MOV AH,02H
	INT 21H
	LOOP D2
	RET
SHOW ENDP						


CODES ENDS
    END START

四、实验结果


在这里插入图片描述

五、注意事项

在ASCII中,39H后是3AH,而不是40H。因此如果需要将A~F转换成对应的数字,需要减去7。笔者当时在这卡了一会,后来突然想到十六进制中是逢十六进一的,希望以上能够帮助到你的实验。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抱歉,我无法为您提供完整的微型计算机实验代码。但我可以给您提供一些关于数据传送的微型计算机实验1的基本知识。 数据传送指的是将数据从一个地方传送到另一个地方。在微型计算机中,数据传送分为两种类型:内部数据传送和外部数据传送。 内部数据传送是指数据在微处理器内部传送,例如从寄存器到寄存器或从寄存器到内存。外部数据传送是指数据在微处理器和外部设备(如输入/输出设备、存储器等)之间传送。 在微型计算机实验1中,您需要了解以下内容: 1. 内部数据传送的指令和操作码 2. 外部数据传送的指令和操作码 3. 内存地址的编码方法 4. 数据传送的实现方法 在数据传送实验中,您需要编写程序来实现将数据从一个位置传送到另一个位置。此外,您还需要使用微型计算机实验箱中的设备(如键盘、显示器等)来进行输入和输出。 下面是一个简单的数据传送实验示例代码: ``` ORG 100H ;程序起始地址 MOV AX, 1234H ;将数据1234H存放到AX寄存器中 MOV BX, AX ;将AX寄存器中的数据传送到BX寄存器中 MOV CX, 5678H ;将数据5678H存放到CX寄存器中 MOV [1000H], CX ;将CX寄存器中的数据传送到内存地址1000H中 MOV DX, [2000H] ;将内存地址2000H中的数据传送到DX寄存器中 HLT ;程序结束 ``` 在上面的示例代码中,我们使用了MOV指令来实现数据传送。MOV指令用于将数据从一个位置传送到另一个位置。在这个例子中,我们将数据存放到寄存器和内存中,并将数据从内存中传送到寄存器中。 在编写完代码后,您需要使用微型计算机实验箱来进行编译和运行。在运行程序时,您需要在键盘上输入数据,并在显示器上查看输出结果。 希望这些信息对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值