【问题标题】:ARM shift left or arithmetic right depending on the sign of the shift count to effectively multiply by any power of 2ARM 左移或算术右移取决于移位计数的符号以有效乘以 2 的任何幂
【发布时间】:2019-03-02 14:06:47
【问题描述】:

我们最近开始学习汇编代码,并且在这个主题上有了家庭作业。我们一直在研究 ARM,必须在 Raspberry Pi 中编写代码。我的一个家庭作业问题是这样的:

编写实现以下 C 函数的汇编函数:

int32_t shiftS32(int32_t x, int32_p) // 返回 x*2^p for p = -31..31

这是我对这个问题的回答:

.global shiftS32  
.text  

shiftS32:  

PUSH {R0}   
CMP R0, #0   
BMI ENDA 
PUSH {R1}  
CMP R1, #0    

BMI END1   
POP {R1}  
MOV R0, R0, LSL R1  

BX LR

END1:
POP {R1}
SUB R1, #0
NEG R1, R1
MOV R0, R0, LSR R1 

BX LR

ENDA: 
PUSH {R1}
CMP R1, #0

BMI END 
POP {R1}
MOV R0, R0, LSL R1

BX LR

END:
POP {R1}
SUB R1, #0
NEG R1, R1
MOV R0, R0, ASR R1 

BX LR

此代码有效,但我认为我做得过火了。 有没有办法用更少的行来做同样的事情?

【问题讨论】:

    标签: assembly arm


    【解决方案1】:

    是的,代码有点太多了。

    您希望使用this trick 来实现有符号整数除法的移位,同时仍保持n / 2 的舍入语义(向0),这与向-infinity 舍入的移位不同。

    您可能想要使用条件执行。

    您的代码可以短至this:

    shiftS32:
            cmp     r1, #0
            asrlt   r2, r0, #31
            addlt   r3, r1, #32
            lslge   r0, r0, r1
            rsblt   r1, r1, #0
            addlt   r0, r0, r2, lsr r3
            asrlt   r0, r0, r1
            bx      lr
    

    还有一点测试here

    【讨论】:

    • 非常感谢您的回复。你的方法看起来确实很干净,但问题是我们还没有学会所有这些术语。这就是为什么我不得不求助于粗略的方法。
    • @SugamBanskota 你可以抛出一个条件分支,这很简单。
    • OP 似乎不想要与整数除法匹配的舍入,因为他们可能打算使用 ASR 进行负计数,而不是除法或复杂的仿真。数学问题陈述是乘以一个小数值;如果他们使用 FP,默认情况下他们会得到四舍五入到最近(-偶数)。
    • @PeterCordes 在这种情况下,在不使用任何“高级”技术或说明的情况下设计一个近乎完美的解决方案应该不仅仅是微不足道的。
    • @AlexeyFrunze:是的,没错。就像从零减去(到新寄存器中)并设置标志,并将其用于预测的右/左移位。我认为您可以使用相同的技巧来保存 CMP 指令,但要以寄存器为代价。
    猜你喜欢
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    相关资源
    最近更新 更多