[汇编]实验1.5 实现格雷码到ASCII码的转换

一、 输出ASCII码表
  1. 思路:
    将ASCII码值放在DL寄存器中,然后输出
  2. 源码:
MOV AH,02H	;	写DL中的数据到显示屏
MOV DL,01H	;	将十六进制ASCII码值放到DL
INT 21H		;	输出DL
  1. 应用
DATA SEGMENT
A	DB	'Welcome to 8086','$'
B	DB	'Please input GR code(0000~1111):$'
DATA ENDS

CODE SEGMENT
	ASSUME CS:CODE,DS DATA

START:
	MOV AX,DATA				;	初始化DS段寄存器
	MOV DS,AX
	
	MOV DX,OFFSET A				;	获得字符串A的偏移地址
	MOV AH,09H				;	显示字符串,直到遇到'$'停止(注意:DS要是段首地址,DX要是偏移地址)
	INT 21H
	
	; 实际应用在这一段 
	
	MOV AH,02H				; 	写DL中的数据到显示屏
	MOV DL,0AH				;	将换行符的ASCII码0AH放到DL中
	INT 21H					;	输出DL中的数据

	MOV DX,OFFSET B				;	获得字符串B中的偏移地址
	MOV AH,09H				;	显示字符串B,知道遇到'$'停止(注意,DS要是段首地址,DX要是偏移地址)
	INT 21H

	MOV AX,4C00H				;	程序终止
	INT 21H
	
CODE ENDS 
END START
  1. 结果
    显示ASCII码表结果
二、实现格雷码到ASCII码的转换
  1. 思路:
    格雷码的值作为下标,去GB中查表
  2. 源码:
DATA SEGMENT
A		DB	'Welcome to 8086','$'
B		DB 	'Please input GR code(0000~1111)$'
GR		DB	0,1,3,2,6,7,5,4,12,13,15,14,10,11,9,8
MSG2	DB 13,10,'The GR code is :$'
C		DB 'I'M IN NANJING NORMAL UNIVERSITY','$'
DATA ENDS

CODE SEGMENT
	ASSUME CS:CODE,DS:DATA

START:
	MOV AX,DATA			; 初始化DS
	MOV DS,AX

	MOV DX,OFFSET A		; 取字符串A的偏移地址
	MOV AH,09H			; 输出字符串A
	INT 21H

FIRST:
	MOV AH,02H			; 写DL中的数据到显示屏
	MOV DL,0AH			; 打印换行符
	INT 21H

	MOV DX,OFFSET B		; 获取字符串B的偏移地址
	MOV AH,09H			; 输出字符串B
	INT 21H

	MOV BX,0			; BX初始化,BX用来保存用户输入的格雷码
	MOV CX,4			; CX用来控制循环次数 循环次数为4 格雷码的长度
_IN:
	MOV AH,01H			; 读键盘输入到AL中并回显
	INT 21H
	
	CMP AL,13			; 判断是否是回车键(注意:这一段代码是很好的,可以让用户输入的格雷码长度小于等于4)
	JE SEARCH			; 跳

	ADD BX,BX			; 将和左移一位,相当于乘以2
	
	CMP AL,'0'			; 判断输入的字符是否是'0'
	JE _0_
	
	CMP AL,'1'			; 判断输入的字符是否是'1'
	JE _1_	
		
	JMP FIRST				; 既不是回车,结束输入,也不是0或1,返回FIRST 重新输入

_1_:
	INC BX					; AL是1,BX+1,返回上面左移一位
_0_:
	LOOP _IN:				; AL是0,BX+0,返回上面左移一位

SEARCH:
	MOV SI,0				; 初始化SI=0


; 这一步查表还不太清楚
S1:
	CMP BL,GR[SI]
	JE	DISP				; 如果成功发现,跳转DISP
	INC SI					; 如果没有成功 一个个往下找
	JMP S1	

DISP:
	MOV DL,10				; 将换行写入显示屏
	MOV AH,02H
	INT 21H
	MOV DL,13				; 将回车写入显示屏
	MOV AH,02H
	INT 21H
	
	MOV DX,OFFSET MSG2		; 获取字符串MSG2的偏移地址
	MOV AH,09H				; 打印字符串MSG2
	INT 21H

;	对SI除10取余操作
	
	MOV AX,SI
	MOV CX,0
	
; D1模块:除10取余数操作
D1: 
	MOV AH,0
	MOV BL,10
	DIV BL			; DIV指令 除以字节 AL=商 AH=余数 除以字 AX=商 DX=余数
	MOV DL,AH		; 
	PUSH DX
	INC CX
	CMP AL,0
	JNE D1
	
;	压栈,压的是余数

D2:
	POP DX			; 将数字转成ASCII码字符输出
	ADD DL,30H
	CMP DL,3AH
	JB D3
	ADD DL,02H		;这个地方还不太清楚
    SUB CX,1		; 如果增加这个,那么就是 100
    				; 如果不增加这个 那么就是1033
    				 
D3:
	MOV AH,02H		; 读DL寄存器中的数据到屏幕上
	INT 21H
	LOOP D2
	
	MOV AH,4CH
	INT 21H
	
CODE ENDS
  1. 结果程序运行结果
  2. 上面代码中等以下还不懂。
  3. 比如用户输入了0011,实际的值是3,对应的是八进制的字符2,为什么比较的是BX(3)和GB[SI],而不是直接和下标SI进行比较呢?
  4. 猜想,是否GB中的表格是以字节方式存储的,所以BL是二进制数据,要对二进制数据转成10进制,输出方便用户查看?
  5. 调试SI寄存器,将SI寄存器的值放在AX,分别取AL,AH放到DL中,然后输出到屏幕,结果如下:
    输出两个笑脸,不知道为什么?
  6. 结果:
    输出两个笑脸,不知道为什么。
  7. 实际参与运算的是BL:
始化时:
 	MOV BL,0 (原:MOV BX,0)
运算时:
	ADD BL,BL 	(原:ADD BX,BX)
  1. 明确BL是二进制表示的格雷码,格雷码要和GR[SI]比较,为什么不直接和SI比较呢?
  2. 明白了 将二进制转成10进制那一段代码是比较好的。
  3. 有个疑问就是二进制转成十进制,加上了30H,就可以变成了ASCII码?
  4. 参考资料

汇编输出数字
https://bbs.csdn.net/topics/360259895

  1. 最终明白了,格雷码放在数组里面,对应的下标,是其真正的值;
  2. 原来的想法,格雷码的真实值作为下标,格雷码的ASCII码值对应数组的值。
  3. 遇到问题:
    上述代码运行的时候,如果刚好输入满足整除条件,结果会多0
    还有高位低位的问题。
    解决这两个问题 应该就能完成实验1.4了。
三、将ASCII码转成二进制输出
  1. 学习体会,初始化DL,打印在屏幕上,能够输出ASCII码表,说明DOXBox内置有ASCII码表
  2. 疑问:汇编指令内部,是如何存储数据的?直接二进制还是二进制的补码呢?
  3. 疑问: 如果要将ASCII转成十进制,又如何转换呢?是用循环移位指令?RCL还是逻辑移位指令,还是除法指令呢?
四、知识补充
  1. 格雷码有4位典型格雷码,也有八位格雷码。
  2. 用户输入的数字是ASCII码值,也可以用字符来代替。输入0,比较的是’0’字符0,输入1,比较的是’1’字符。也可以比较ASCII码值。
_IN:
	MOV AH,01H		; 读键盘输入到AL中并回显
	INT 21H

	CMP AL,13		; 判断是否是回车键(注意:这一段代码是很好的,可以让用户输入的格雷码长度小于等于4)
	JE SEARCH		; 跳
  	
  	
  	CMP AL,'0' 		; 判断输入的字符是否是'0'
 	JE _0_
 
 	CMP AL,'1'		; 判断输入的字符是否是'1'
 	JE _1_ 
  1. 第一个比较的是回车,用的是回车的ASCII码值13
  2. 第二个比较的是输入的数字,用的是0和1的字符形式,字符’0’,字符’1’。
四、总结
  1. 程序终止的两种办法
	MOV AH,4CH
	INT 21H
	MOV AX,4C00H
	INT 21H

反思:程序终止只跟高位AH有关
2. 程序开始要写

CODE SEGMENT
	ASSUME CS:CODE
START:

代码块

CODE ENDS
	END START

否则会出现错误:
缺少代码错误
4.

五、参考资料
  1. 80x86汇编语言编程:输入格雷码、输出对应的十进制数字
    https://blog.csdn.net/baidu_33836580/article/details/50578944
  2. 数字 0 - 9 转换成对应的格雷码
    https://blog.csdn.net/baidu_33836580/article/details/50578833
  3. 格雷码与二进制码的转换
    https://blog.csdn.net/hanghang121/article/details/23927465
  4. 汇编学习小记(三)-查表
    https://juejin.im/post/5adb2c57f265da0b7451bdf0
  5. 用汇编语言编写程序打印ASCII表
    https://blog.csdn.net/ljianhui/article/details/17273431
  6. 回车、换行、空格的ASCII码值—(附ASCII码表)
    https://blog.csdn.net/songjinshi/article/details/7868866
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值