压缩十进制到 ASCII 汇编
我正在尝试将压缩十进制数转换为 ascii 字符串。到目前为止,这是我的理解:
如下:
bcd BYTE 34h
“解压”后应转换为十进制数 34。现在我不确定这样做的最佳方法。如果我将这个十六进制数转换为二进制数,则如下...
0011 0100
现在,如果我让程序一次打印出每个 4 位二进制值,那么它应该打印 ascii 数字字符串,对吗?因此,如果我经历一个循环,获取第一个 4 位二进制数,打印出其实际值,它将打印 3.. 然后执行相同的操作,它将打印 4。
所以,这是我的总体想法
: 8bit值“34h”,将其移入AH和AL。在 AH 中,使用以下命令清除后半部分位:
and ah, 11110000b
在 AL 中,使用以下命令清除前半部分位:
and al, 00001111b
因此 AH = 0110b 或 3 AL = 0100b 或 4,然后相应地打印出来。
这是一个好方法吗?或者我是否完全错误或想得太多了?
编辑:这是我的最终解决方案,原始值为 12345678h。感谢所有提供帮助的人!
;-----------------------------------------------------------------------------
PackedToAsc PROC USES eax ebx edx ecx esi
; This function displays a packed decimal value in its "ascii" form
; i.e. 12345678h would display decimal, 12345678 in decimal form
;
; Requires ECX = SIZEOF packed decimal
; ESI to be pointing to the packed decimal
;-----------------------------------------------------------------------------
mov edx, [esi] ; temp store our offset
mov eax, 0 ; clear eax
mov ebx, 0 ; clear ebx
L1: rol edx, 8 ; rotate left 8 bits to avoid little endian
mov [esi], edx ; mov our temp back to the actual value
mov al, BYTE PTR [esi] ; al = 12h 0001 0010
mov bl, BYTE PTR [esi] ; bl = 12h 0001 0010
shr al, 4 ; al = 0000 0001
and bl, 00001111b; ; bl = 0000 0010
add al, 48 ; convert to ascii
call WriteChar ; display al
mov al, bl
add al, 48 ; convert to ascii
call WriteChar ; display bl
loop L1
call Crlf
ret
PackedToAsc END
磷
I'm trying to convert packed decimal numbers into ascii strings. Here is my understanding thus far:
The following:
bcd BYTE 34h
Should convert to the decimal number 34 after being "unpacked". Now I'm not sure on the best way of doing this. If I convert this hexadecimal number to binary it is as follows...
0011 0100
Now, if I have my procedure print out each 4bit binary value at a time, then it should print the ascii string of numbers, correct? So if I go through a loop, grab the first 4 bit binary number, print its actual value out, its going to print 3.. then do the same, its going to print 4.
So, here is my general idea:
Take an 8bit value "34h", mov it into AH and AL. In AH, clear the second half of the bits using the follow:
and ah, 11110000b
and in AL, clear the first half of the bits using the following:
and al, 00001111b
So AH = 0110b or 3
And AL = 0100b or 4, then print these out accordingly..
Is this a good approach? Or am I going about completely incorrect or way over thinking it?
EDIT: Here is my final solution with original value of 12345678h. Thanks to all who helped!
;-----------------------------------------------------------------------------
PackedToAsc PROC USES eax ebx edx ecx esi
; This function displays a packed decimal value in its "ascii" form
; i.e. 12345678h would display decimal, 12345678 in decimal form
;
; Requires ECX = SIZEOF packed decimal
; ESI to be pointing to the packed decimal
;-----------------------------------------------------------------------------
mov edx, [esi] ; temp store our offset
mov eax, 0 ; clear eax
mov ebx, 0 ; clear ebx
L1: rol edx, 8 ; rotate left 8 bits to avoid little endian
mov [esi], edx ; mov our temp back to the actual value
mov al, BYTE PTR [esi] ; al = 12h 0001 0010
mov bl, BYTE PTR [esi] ; bl = 12h 0001 0010
shr al, 4 ; al = 0000 0001
and bl, 00001111b; ; bl = 0000 0010
add al, 48 ; convert to ascii
call WriteChar ; display al
mov al, bl
add al, 48 ; convert to ascii
call WriteChar ; display bl
loop L1
call Crlf
ret
PackedToAsc END
P
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
BCD 仅使用数字 0 到 9。
未压缩的 BCD 数字使用整个字节的低半字节,并将其转换为 ASCII,添加 48。
数字 34h 是十进制的 52,将表示为未压缩的 BCD,如 00000101 和 00000010
(已更改以避免使用内置指令时发生混淆)
打包时: 01010010 == BCD 打包 52
要解包,您可以按照您所做的操作,但需要将 AH 右移以将值放入低半字节中。要转换为 ASCII,只需添加 48。
[编辑]
在 80x86 处理器上运行的 MASM(=> 所有指令,包括 Linux)使用小端模式。 Motorola 68000 (Apple Mac) 和 RISC 等 CPU 使用大端字节序。
当您将数字存储为 BCD 时,最低有效字节位于最低地址,直到最高有效字节位于最高地址,例如:
压缩 BCD 取决于您想用它做什么。如果您想要
ADD、MUL、DIV、SUB
,您必须按照这些指令的要求提供值。还要记住在数字的开头和结尾添加零字节以保存进位。BCD uses only the digits 0 thru 9.
An unpacked BCD digit uses the lower nibble of an entire byte and to convert it to ASCII you add 48.
The number 34h is 52 decimal and will be represented as an unpacked BCD as 00000101 and 00000010
(Changed to avoid confusion when using built-in instructions)
When it is packed: 01010010 == BCD packed 52
To unpack it, you can do as you have done, but you need to shift AH right to place the value in the lo-nibble. To convert to ASCII just add 48.
[edit]
MASM (=> ALL instructions, Linux included) that runs on 80x86 processors uses the little-endian scheme. CPUs such as Motorola 68000 (Apple Mac) and RISC uses big-endian.
When you store a number as BCD, the least significant byte is at the lowest address thru to the most-significant at the highest, e.g.:
Packed BCD depends on what you want to do with it. If you want to
ADD, MUL, DIV, SUB
you must present the values as required by these instructions. Also remember to add zero-bytes to start and end of your digits to hold carries.