【问题标题】:Is there a way to write single instruction for fractional multiplication?有没有办法为小数乘法编写单指令?
【发布时间】:2020-10-22 02:01:38
【问题描述】:

我正在尝试编写一条 68000 指令来将 D0 中的 32 位无符号值乘以 0.125。然而分数乘法不可用。所以我想知道是否有任何方法可以绕过它?它应该是无符号的并且 0.125 = 1/8。因此,我认为它的工作方式是:

LSL (LSR #0,#3),D0

这甚至没有运行,我不知道我还能怎么做。

【问题讨论】:

标签: assembly multiplication fractions 68000 easy68k


【解决方案1】:

不确定你想要达到什么目的:

LSL (LSR #0,#3),D0

如果您想将d0 中的值逻辑右移三位(即除以8,或乘以0.125),那会简单得多:

lsr #$03, d0 ;; or lsr.l

【讨论】:

    【解决方案2】:

    这是汇编,你不能只是组合这样的指令组合表达式。每条指令都需要在自己的行上。如果你想实现(x >> 3) << 3,你必须先右移,然后左移,这是两个独立的指令:

    LSR.L #3,D0
    LSL.L #3,D0
    

    顺便注意(x >> N) << N等价于x & -(1 << N),在N=3的情况下是:x & -8,或者在68k汇编中AND.L #-8,D0(或者在十六进制中AND.L #$fffffff7,D0)。

    但是,如果您只想乘以 0.125(即除以 8),则右移一次就足够了:

    LSR.L #3,D0
    

    【讨论】:

    • 如果你想四舍五入到8的倍数,一条and指令可以比右移+左移更有效。
    • @PeterCordes 是的 .. 不知道 OP 真的用那个“指令”做了什么。
    • 我也不是,但这就是你的 lsr + lsl 组合所做的,所以你应该优化它而不是建议你想在程序中使用一系列指令。我假设 m68k 具有 AND 指令的符号扩展立即数,或者最坏的情况是 and 不大于 2 个班次。
    • @PeterCordes 好吧,当然,但我并不是要解释舍入的最佳方式,我只是在解释如何正确组合指令。 OP 真正想要的只是一个班次。不管怎样,我只是为了它而添加它。
    • and #-8, d0 确实实现(x >> 3) << 3。这就是编译器所做的(对于其他 ISA)godbolt.org/z/rf5qa8,所以说你 必须 使用轮班来做这件事有点言过其实。仅当您想按书面方式实现它时。我看到你已经更新了,但你倒退了:x & 7x<<(16-3) >> (16-3) 只保留低 3 位,而不是清除那些。
    猜你喜欢
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    相关资源
    最近更新 更多