打印一個ASCII表在高級程序設計語言中是一個非常簡單的程序,但是用匯編又該如何編寫呢?
一、設計思路
我們可以按15行*16列的表格形式顯示ASCII碼爲10H一100H的所有字符,即以行爲主的順序及ASCII碼遞增的次序依次顯示對應的字符。每16個字符爲一行,每行中的相鄰兩個字符之間用空白符(ASCII爲0)隔開。
顯示每個字符可使用功能號爲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中運行該程序即可正確輸出。