用汇编语言编写程序打印ASCII表

打印一个ASCII表在高级程序设计语言中是一个非常简单的程序,但是用汇编又该如何编写呢?


一、设计思路

我们可以按15行*16列的表格形式显示ASCII码为10H100H的所有字符,即以行为主的顺序及ASCII码递增的次序依次显示对应的字符。每16个字符为一行,每行中的相邻两个字符之间用空白符(ASCII0)隔开。

显示每个字符可使用功能号为02的显示输出功能调用,使用方法如下:

     Mov       ah,02h

     Mov       dl,输出字符的ASCLL码

     Int       21h

    可把dl初始化为10H,然后不断使其加1(用INC指令)以取得下一个字符的ASCLL码。


显示空白符时,用其ASCLL码0置入dl寄存器。每行结束时,用显示回车(ASCLL为0dh)和换行符(ASCLL为0ah)来结束本行并开始下一行。


由于逐个显示相继的ASCLL字符时,需要保存并不断修改dl寄存器的内容,而显示空白,回车,换行符时也需要使用dl寄存器,为此可使用堆栈来保存相继的ASCLL字符。具体用法是:在显示空白或回车,换行符前用指令

                       Push      dx

       把dl的内容保存到堆栈中去。在显示空白或回车,换行符前用指令

                       Pop       dx

       恢复dl寄存器的原始内容。


二、程序实现代码

采用类似于C语言的双层循环输出的方式,在外层循中输出一行,总共循环15次,输出15行;在内层循环中输出一行中的16个字符,循环16次。用DX寄存器保存对应的字符的ASCII值,并增加DX的值来得到下一个ASCII码。


具体实现如下:

assume cs:codesg

codesg segment
	;设置寄存器初值
	mov dx, 0000H
	mov dl, 10H 	;从ASCII码为10H的字符开始显示
	mov cx, 000FH	;设置外循环的次数15,即要显示的行数
	mov ax, 0000H
	
  	r:
  		mov ah, 02H		;设置显示方式
  		push cx			;保存外循环次数的计数
  		mov cx, 0010H	;设置内循环次数16,即一行16个字符
  		
  	c:
  		int 21H			;显示ASCII值为[dl]的字符
		push dx			;保存dx的值
		mov dl, 00H		;输出空格
		int 21H
		
		pop dx			;恢复dx的值,并加1,产生下一个ASCII字符
		inc dx
		loop c
		;已经进行完了一次内循环
		pop cx			;恢复外循环次数的计数
		push dx			;保存dx的值
		
		mov dl, 0dH		;输出回车换行
		int 21H
		mov dl, 0aH
		int 21H
		
		pop dx			;恢复dx的值
		
		loop r
		;外循环结束,程序的功能完成
	mov ax, 4c00H
	int 21H
codesg ends
end
运行结果如下:



三、程序分析

代码采用类似于C语言的双层循环输出的方式,在外层循中输出一行,总共循环15次,输出15行;在内层循环中输出一行中的16个字符,循环16次。用DX寄存器保存对应的字符的ASCII值,并增加DX的值来得到下一个ASCII码。


由于在输出空格、回车和换行时,会破坏DX中原来的值,所以在用空格、回车和换行的ASCII值覆盖DX寄存器原来的内容时,先把DX寄存器中的内容压入栈中保存,即PUSH DX。输出空格、回车和换行后,调用POP DX恢复DX寄存器的值。以便下次直接把DX的值加1产生后继字符。


由于本程序中使用了两个循环,而每一个循环中都要用CX保存和记录循环的次数,所以在进入内层循环时,要先把外层循环的计数,即用PUSH CX,把CX的值压栈保存。在内层循环结束时,再恢复外层循的计数,即POP CX。然后在LOOP指令中判断外层循环是否完成退出。


PS:由于所用的操作系统问题,在运行程序时后面一些行(ASCII码为128及以后的行)有时会显示乱码。可用虚拟软件虚拟16位系统或在Debug中运行该程序即可正确输出。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章