【问题标题】:Converting hex digits to corresponding decimal digits将十六进制数字转换为相应的十进制数字
【发布时间】:2020-03-24 16:40:47
【问题描述】:

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

【问题讨论】:

  • (al >> 4) * 10 + (al & 0Fh)
  • 35 = (3*10) + 5

标签: assembly hex decimal intel masm


【解决方案1】:

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

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

请注意,它不是任意的十六进制字符串,甚至不与 ASCII 中的数字一起存储。因此,您不必做任何事情来处理 ASCII '0'..'9' 在 'A'..'F' 之前有一个间隙的事实,就像您实际上将数字字符串视为非规范化基数一样10,数字值为 0..15,位值为 10^n。

您刚刚打包了 BCD。是的,这些位的 base-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 Adjust AX After Multiply),默认立即数为 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    相关资源
    最近更新 更多