【计算机与UNIX汇编原理⑨】——实验报告一【题目:排除语法错误、统计数字】

本文详细介绍了两部分汇编语言实验。第一部分涉及修复8位二进制数转换为十进制显示的源程序,通过调试和理解汇编指令,最终实现正确显示25+9=34。第二部分设计了一个程序,统计并以8位二进制形式显示ASCII码在42H~45H之间的字符个数,例如在'NJUPT_ABC$'中找到了2个符合条件的字符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >




Experiment 时刻!⌨️

上一篇文章链接:【计算机与UNIX汇编原理⑧】——UNIX编程进阶【分支程序、循环程序、子程序、宏指令】.
下一篇文章链接:【计算机与UNIX汇编原理⑩】——汇编语言程序设计举例【三种进制转换】.


一、排除语法错误【实验内容一】

  ● 题目描述:下面给出的是一个通过比较法完成 8 位二进制数转换成十进制数送屏幕显示功能的汇编语言源程序,但有很多语法错误。要求实验者按照原样对源程序进行编辑,汇编后,根据 MASM 给出的错误信息对源程序进行修改,直到没有语法错误为止。然后进行链接,并执行相应的可执行文件。正确的执行结果是在屏幕上显示 25+9=34 。

  ● 右边的注释是我后面加的(主要错误)

"右边的注释是我后面加的(主要错误)"

;FILEANAME:		EXA131.ASM
.486							

DATA 	SEGME	-NT	USE16		
		SUM		DB ?, ?,		
		MESG	DB '25+9='		; 可以和下面句进行整合, 记得加结束符号 “$”
				DB 0, 0
		N1		DB 9, F0H		; 多了个 FOH
		N2		DW 25
DATA	ENDS

CODE	SEGMENT USE16
		ASSUME 	CS:CODE, DS:DATA
		
BEG:	MOV 	AX, DATA
		MOV 	DS, AX
		MOV		BX, OFFSET SUM
		MOV 	AH, N1
		MOV 	AL, N2
		ADD 	AH, AL
		MOV		[BX], AH			; PTR 的应用(包括后面)
		CALL 	CHANG
		MOV 	AH, 9
		MOV 	DX, OFFSEG MEST
		INT 	21H
		MOV 	AH, 4CH
		INT 	21H

CHANG: 	PROC						; 子程序格式
LAST:	CMP 	[BX], 10
		JC		NEXT
		SUB 	[BX], 10
		INC 	[BX+7]
		JMP		LAST

NEXT: 	ADD		[BX+8], SUM			; 没有这种寻址方式
		ADD		[BX+7], 30H
		ADD 	[BX+8], 30H
		RET

CHANG: 	ENDP		
CODE	ENDS
END BEG	

  ● 修改后的代码如下图所示

;FILEANAME:		EXA131.ASM
.586						; 我们一般用 .586

DATA 	SEGMENT	USE16
		SUM		DB ?, ?
		MESG	DB '25+9=', 0, 0, '$'
		N1		DB 9
		N2		DW 25
DATA	ENDS

CODE	SEGMENT USE16
		ASSUME 	CS:CODE, DS:DATA
		
BEG:	MOV 	AX, DATA
		MOV 	DS, AX
		MOV		BX, OFFSET SUM
		MOV 	AH, N1
		MOV 	AL, BYTE PTR N2				; N2 为字属性, 需要改一下
		ADD 	AH, AL						; 实现加法
		MOV		[BX], AH					; 规则里没有,所以我们默认是对的
		
		CALL 	CHANG
		
		MOV 	AH, 09H						; 显示字符串
		MOV 	DX, OFFSET MESG				; 前面只有名为 “MESG” 的变量
		INT 	21H
		
		MOV 	AH, 4CH						; 终止
		INT 	21H

CHANG 	PROC								; 不需要 ":"
LAST:	CMP 	BYTE PTR [BX], 10			; 违反双操作数第(2)条规则, 需要改一下
		JC		NEXT						; < 10 的话(发生借位), 进行跳转	
		SUB 	BYTE PTR [BX], 10			;10 操作
		INC 	BYTE PTR [BX+7]				; 逢十进一
		JMP		LAST						; 无条件转移指令

NEXT: 	;MOV		[BX+8], SUM				; 源操作数和目的操作数不能同时为存储器
		MOV		AH, [BX]					; [BX] 也可以换成 SUM
		MOV 	[BX+8], AH
		ADD		BYTE PTR [BX+7], 30H		; 十位转换为 ASCII
		ADD 	BYTE PTR [BX+8], 30H		; 个位转换为 ASCII
		RET
CHANG 	ENDP								; 不需要 ":"
CODE ENDS
END	BEG


  ● 思考与小结一:该实验主要训练我们的 “调试” 能力(如下图所示),还有对于基础知识点的理解。这里有一个关键点,SUM 变量和 BX 其实是同一个东西,当 BX 发生变化时,SUM 也会发生变化。

在这里插入图片描述


  ● 思考与小结二:一般 DS:DX 指向放键入字符的缓冲区,但字符串的储存形式和一般的不太一样。所以 [ B X + 2 ] [BX+2] [BX+2] 其实才是 “25+9=” 中的 “2”。
在这里插入图片描述

  ● 思考与小结三:MOV AX,BX 是把寄存器 BX 中的内容给 AX。而 MOV AX,[BX] 是先把 BX 中的内容取出来,作为偏移地址,算出物理地址,再把这个地址的内容送给 AX。(比如说 BX 中的内容是 1021,就是去把地址为 1100 内存单元的数据送给 AX)。另外,[BX+7] 是基址寻址,参考文章: 【计算机和UNIX汇编原理④】——指令系统(上)【标志寄存器 立即寻址 寄存器寻址 直接/寄存器/基址/变址寻址 万字总结】.

  ● 修改的第二种方法:先输出 “25+9”,然后依次输出 “3” 和 “4”(单字符)。

;FILEANAME:		EXA131.ASM
.586						; 我们一般用 .586

DATA 	SEGMENT	USE16
		SUM		DB ?, ?
		MESG	DB '25+9=', '$'
		N1		DB 9
		N2		DW 25
DATA	ENDS

CODE	SEGMENT USE16
		ASSUME 	CS:CODE, DS:DATA
		
BEG:	MOV 	AX, DATA
		MOV 	DS, AX
		MOV 	AH, N1
		MOV 	AL, BYTE PTR N2				; N2 为字属性, 需要改一下
		ADD 	AH, AL						; 实现加法
		MOV		SUM, AH				
		
		MOV 	AH, 09H						; 显示字符串
		MOV 	DX, OFFSET MESG				
		INT 	21H
		
		CALL 	CHANG
		
		MOV 	AH, 4CH						; 终止
		INT 	21H

CHANG 	PROC
											
LAST:	CMP 	BYTE PTR SUM, 10			
		JC		NEXT						; < 10 的话(发生借位), 进行跳转	
		SUB 	BYTE PTR SUM, 10
		INC 	BYTE PTR BH					; 逢十进一
		JMP		LAST						; 无条件转移指令

NEXT: 	
		ADD		BYTE PTR BH, 30H			
		MOV 	AH, 02H						; 显示单字符
		MOV 	DL, BH
		INT 	21H
		
		ADD 	BYTE PTR SUM, 30H			; 个位转换为 ASCII	
		MOV 	AH, 02H						
		MOV		DL, SUM						
		INT 	21H

		RET
CHANG 	ENDP								
CODE ENDS
END	BEG

  ● 运行结果

在这里插入图片描述



二、统计数字【实验内容二】

  ● 题目描述:设计一个汇编程序,要求在数据段中预存放 10 个字符,统计 ASCII 码在 42H~45H 之间的字符个数并且以 8 位二进制的形式显示在屏幕上。

  ● 程序框图

在这里插入图片描述

  ● 代码如下

.586

DATA	SEGMENT USE16
		BUF	DB	'NJUPT_ABC$'	
		COUNT EQU $-BUF				; 统计串的长度
		TIM	DB 0
DATA	ENDS

CODE 	SEGMENT	USE16
		ASSUME 	CS:CODE, DS:DATA
		
BEG:	MOV 	AX, DATA
		MOV 	DS, AX
		MOV 	BX, OFFSET 	BUF
		MOV		CL, COUNT				; 循环 COUNT 次
		MOV 	DL, 0					; 记录 42H~45H 之间的字符个数
		
FIRST:	CMP		BYTE PTR [BX], 42H
		JC 		NEXT_1					; < 42H 时转
		CMP 	BYTE PTR [BX], 45H
		JA 		NEXT_1					; > 45H 时转
		INC 	DL
		
NEXT_1: INC 	BX
		DEC 	CL			
		JNZ		FIRST
		
		; ADD		DL, 30H		; 将 DL 中存储的数字转化为 ASCII 码
		;MOV 	AH, 2		   	; 功能号02H(显示)
		;INT 	21H
		
		MOV 	CX, 8			; 8 位二进制显示
		
SECOND:	MOV		AL, '0'			; 0 的 ASCII 码
		ROL 	DL, 1			; (不含进位的循环)左移
		JNC 	NEXT_2			; 若当前 C 标志为 0, 则进行转移
		MOV 	AL, '1'			; 1 的 ASCII 码
	
NEXT_2:	MOV 	AH, 0EH			; 单字符显示
		INT 	10H
	 
		LOOP 	SECOND			; CX 将执行减 1 操作, 小于 0 时跳出循环

		MOV		AH, 4CH
		INT 	21H
		
CODE 	ENDS
END 	BEG

  ● 运行结果:

在这里插入图片描述

  ♦ 结果说明:42H 是 “B” 的 ASCII 码,45H 是 “E” 的 ASCII 码。“NJUPT_ABC$” 中有 2 个ASCII码在 42H ~ 45H 区间里面。



三、参考附录

[1] 《微型计算机原理与接口技术(慕课板)》
清华大学出版社

[2] 《汇编语言程序设计(第2版)》

[3] 《ASCII码一览表,ASCII码对照表》
链接: http://c.biancheng.net/c/ascii/.

[4] [bx]和bx有何区别?
链接: https://bbs.csdn.net/topics/30270849.

上一篇文章链接:【计算机与UNIX汇编原理⑧】——UNIX编程进阶【分支程序、循环程序、子程序、宏指令】.

下一篇文章链接:【计算机与UNIX汇编原理⑩】——汇编语言程序设计举例【三种进制转换】.


⭐️ ⭐️

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一支王同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值