assembly - 将表示 Short 的两个字节乘以 1.5

标签 assembly bit-manipulation z80

我正在查看一些汇编代码,并发现了以下内容(为了方便读者,我已对其进行了转换)。所有寄存器都是8位,指针是16位。因此 (q) 加载 8 位。

(q+1) = (q+1) = rr(q+1) 其中 (q) 取消引用 qrr(q) 向右旋转 (q) = (q) + (q)/2 + bit((q+1), 0) 其中 bit((q+1), 0) 是获取(q+1)

的第0位

这真的让我很困惑,因为上面的代码所做的是将 16 位值乘以 1.5,无论其字节序如何(即,无论您如何解释 q,无论是小端字节序还是大字节序,它的值都会在各自的字节序中乘以 1.5字节序)。

我对他们如何使用两个 8 位值将 16 位值乘以 1.5 感到困惑。这里发生了什么?具体来说,将(q+1)的第0位添加到(q)的目的以及将(q+1)向右旋转的目的是什么?

这是汇编代码:

ld a, (q)
ld b, a
ld a, (q+1)
ld c, a
srl b
rr c
add c
ld (q+1), a
ld a, (q)
adc b
ld (q), a
ret

最佳答案

我没有花时间详细阅读所有汇编代码,但我强烈怀疑@Ross Ridge 是对的。

这个技巧称为霍纳法。它在没有乘法器的小型嵌入式 MCU 中尤其常见,但可用于一般速度优化。参见

http://www.ti.com/lit/an/slaa329/slaa329.pdf

关于assembly - 将表示 Short 的两个字节乘以 1.5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32322646/

相关文章:

assembly - Z80 汇编程序/机器代码中的字节/字/地址是有符号的还是无符号的?

interrupt - 无法弄清楚如何使用 SDCC 为 Z80 编写中断处理程序

c - 我怎样才能用当前的 IP 和 BP 寄存器找出完整的调用堆栈?

c - 如何在x86-64架构上使用INVLPG?

x86 - 机器代码如何访问子程序调用的参数?

C 位运算左移和按位或

assembly - 无法让 .define 与 sdasz80(sdcc 汇编程序)一起使用

c++ - Arduino 内联 ASM 未按预期工作

c - 使用算术比存储变量更快吗?

将 C 校验和函数转换为 Lua