; AL = the digit you wish to print, ranges from 0x00 to 0x0F
cmp al,0Ah
jb noCorrectHex
add al,7 ; converts 0x0A to 0x41 = 'A' , 0x0B to 0x42 = 'B', etc.
noCorrectHex:
add al,'0' ; evaluates to "add al,30h"
PrintHex:
; AL = the byte you wish to print.
; this prints the hexadecimal representation of a byte to the screen.
push ax
shr al,1
shr al,1
shr al,1
shr al,1
call PrintHexChar
pop ax
and al,0Fh
;fallthrough is intentional
PrintHexChar:
cmp al,0Ah
jb noCorrectHex
add al,7 ; converts 0x0A to 0x41 = 'A' , 0x0B to 0x42 = 'B', etc.
noCorrectHex:
add al,'0' ; evaluates to "add al,30h"
mov ah,02h
mov DL,AL
int 21h
ret
2条答案
按热度按时间gblwokeq1#
在
AH
设置为09H
的情况下调用21H
中断,将打印寄存器DX
中以$
结尾的字符串。在您的情况下,DX
包含31H
,这将指向(我假设)垃圾,这就是为什么您打印随机符号。在调用print syscall之前,在数据段中创建要打印的字符串,并使
DX
寄存器指向它。5hcedyr02#
我认为这里有一点误解,还没有解决。存储在计算机内存中的数字不能按原样打印。在汇编中,数字必须转换为字符串,并且您需要打印该字符串。谢天谢地,这相当简单。因为ASCII被设计成0到9的任何一位数的基数为10的数字的字符串表示是它的值加上
0x30
。也就是说,'0' = 30h
,'1' = 31h
等。唯一的问题是默认情况下数字是以二进制存储的,这意味着将数字打印为十六进制比打印为十进制要容易得多。0x0n
形式的单个十六进制数字到其ASCII值的转换因子相当容易:如果你从你的单词的最左边的数字开始(在把它从存储器装入寄存器之后),然后从左到右,你可以用这个方法按顺序打印数字。我用DOS中断打印单个字符,而不是字符串。
这里有另一种方法来执行数学转换一个十六进制数字到ASCII,这是有点难以遵循的事情,但它不需要任何分支(我不知道这是更好或更坏,只是做更可读的版本,但你得到相同的结果)