将十六进制数字转换为相应的十进制数字

问题描述 投票:-2回答:1

所以我在家庭作业中有这个问题,我不知道我是否正确理解。它说:*编写汇编代码以将AL中的压缩BCD字节转换为二进制。示例:假设Al = 35H,代表十进制数字35。应将其转换为00100011 =23H = 2 * 16 + 3 = 35d。*根据我的理解,它需要我将十六进制数字转换为十进制数字。即35H至35d。有人可以确认这是在问什么吗?如果是这样,有人可以帮助我实现一种算法吗?

assembly hex decimal intel masm
1个回答
0
投票

正如@Michael所说,您只需要计算(al >> 4) * 10 + (al & 0Fh)

您显然可以假设输入是正确的BCD,字节的两个半字节都在0到9之间,并存储了单独的十进制数字。

请注意,它不是任意的十六进制字符串,甚至都不会与ASCII数字一起存储。因此,您无需采取任何措施来处理ASCII'0'..'9'在'A'..'F'之前有一个空格的事实,就像您实际上将数字字符串视为非标准化基数一样10,位数为0..15,位值为10 ^ n。

您刚刚打包了BCD。是的,这些位的基数为16的解释将为您提供0x35。

但是您想要一个二进制整数,该整数表示的值与将这些半字节视为十进制数字时的值相同,位置值为10 ^ n。因此,您将半字节分开,并将高半字节乘以10。


如果您不关心性能,则可以使用x86的旧版ASCII / BCD指令。它们提供16位和32位模式。 (x86-64删除了BCD指令)。这里唯一的好处就是代码大小:两条2字节指令可以很慢地完成工作。

    aam 16          ; split AL into AH = AL/16; AL = AL%16
    aad             ; AL = AH*10 + AL;  AH=0

aam使用除法,因此它可以用于任何立即数;以2的幂使用它对性能非常低效,仅对代码大小有利。预期的用途是将二进制整数拆分为2个未压缩的十进制数字(乘以ASCII后调整AX),默认的立即除数为10

我们想要的AAD的默认立即数也是10

[https://www.felixcloutier.com/x86/aamhttps://www.felixcloutier.com/x86/aad

[没有dad指令对AL中的压缩BCD进行相同的乘法运算,仅对DAA和DAS(加/减后)进行相同的乘法。


有效地做(为了提高性能而不是代码大小)留给读者练习。 (或者对于编译器; GCC在乘积部分使用2x LEA做得很好:https://godbolt.org/z/K-tjXv

© www.soinside.com 2019 - 2024. All rights reserved.