【问题标题】:Clear upper 16-bits in 1 ARM instruction在 1 条 ARM 指令中清除高 16 位
【发布时间】:2008-11-16 18:49:08
【问题描述】:

在 ARM 汇编中,立即数由 8 位旋转值编码,这意味着我们只能编码

(0-256)^2n.

现在我的问题是我想清除 r0 的高 16 位并将其替换为存储的半字 r1。但是由于我必须做的立即数范围有限:-

bic r0, r0, #0xff000000
bic r0, r0, #0x00ff0000
add r0, r0, r1, LSL #16

是否可以用一条指令替换 2 条 bic 指令? 0xffff0000 是不可编码的。也许我应该使用另一个逻辑运算来清除高 16 位?

谢谢

编辑:对不起,我忘了说 r1 的前 16 位是空的,我使用的是 ARM7TDMI

【问题讨论】:

    标签: assembly arm bit-manipulation


    【解决方案1】:

    如果您有足够新的 ARM 内核,问题很简单:

    movt    r0, #0
    orr     r0, r0, r1,lsl#16
    

    见http://www.keil.com/support/man/docs/armasm/armasm_cjagdjbf.htm

    但是,如果您确实有 ARMv6+,您实际上可以一口气完成整个引用的示例:

    pkhbt   r0, r0, r1,lsl#16
    

    见http://www.keil.com/support/man/docs/armasm/armasm_cihjedjg.htm

    【讨论】:

    • Keil 声称它们可用作 ARM 指令以及 Thumb。我个人从来没有理由在愤怒中使用 ARMv4 以外的任何东西,但我相信它们应该可以工作。
    • 编辑:“我正在使用 ARM7TDMI” — ARM7TDMI 是 ARMv4,或者可能是 ARMv5……遗憾的是,无论哪种方式都不足以具有“movt”或“pkh”。
    【解决方案2】:

    怎么样:

    orr r0,r1,r0,lsl #16
    mov r0,r0,ror #16
    

    (这假设 r1 的上半字为空,就像您的参考代码一样。) 根据具体情况,您可以通过将最后的 mov 与稍后的代码合并来省略此处的最终 mov。

    【讨论】:

      【解决方案3】:

      “将其替换为存储的半字 r1”——这是否意味着您可以假设 r1 的前 16 位为零?如果是这样,

      add r0, r1, r0 lsl #16
      mov r0, r0 ror #16
      

      将 mov 视为占位符,因为您可以希望将 ror 移动到下一个将 r0 作为输入的任何位置,并在同一循环中实际执行有用的工作。

      【讨论】:

        【解决方案4】:

        在 ARMv6(例如 MPCore)上,你可以说

            uxth    r1, r1
            orr     r0, r1, r0, asl #16
        

        【讨论】:

          【解决方案5】:

          如果你能清除整个事情,你可以xor它本身。

          如果您需要保留下半部分,您是否可以将寄存器左移 8 位并返回?不过,这可能是相同数量的指令。

          【讨论】:

            【解决方案6】:

            对于 C 代码

             (a<<16)|((short)b)
            

            gcc 生成

                mov     r1, r1, asl #16
                mov     r1, r1, asr #16
                orr     r0, r1, r0, asl #16
            

            它不使用任何立即数 - 但它仍然是两条指令。

            【讨论】:

            • 是的,我认为这是等效的(相反,r0 和 r1)。但正如沃伦所说,我必须左右移动,这仍然是相同数量的指令。
            • 你忘了让编译器知道b的高16位是干净的。如果您尝试int merge(int a, short b) { return (a &lt;&lt; 16) | b; } GCC 输出 bobince 建议的内容:)。向编译器提供你所知道的一切是一种很好的做法。
            【解决方案7】:

            您可以使用 BFC 指令。位字段清除。该指令从 m 位中清除 n 位

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-06-17
              • 1970-01-01
              • 2012-04-05
              • 2011-11-27
              • 1970-01-01
              • 2023-01-31
              相关资源
              最近更新 更多