是否可以定义一个函数,以便覆盖其中一个参数?

时间:2011-12-06 08:53:40

标签: assembly arm

我定义了一个名为multiply的函数,它接受参数R0和R1并将结果保存在R3中。这很糟糕,因为每当我调用multiply时,我必须将操作数放在R0和R1中,并将R0,R1和R3中的操作数移到其他地方。有没有办法使函数采取形式乘以R4,R5,R6类似于如何添加R1,R2,R3

ldr R0, =snakes
ldr R1, [R0], #4
mov R2, #15
mov R3, #6

如果我想将R2和R3相乘,则需要额外的工作。我经常多次调用,我想知道是否有更好的方法?

Multiply:
    stmfd   sp!,{r0-r2, lr}
    mov R2, #1
    mov R3, #0 
    repeat:
        add R3, R1, R3  
        add R2, R2, #1
        cmp R2, R0
        ble repeat
    mov R2, R3
    LDMFD   sp!,{r0-r1, pc}

2 个答案:

答案 0 :(得分:0)

许多汇编程序都支持宏。看看你的汇编程序是否支持它们,它们将有助于消除不必要的寄存器存储和加载。您只需指定r0,r1,r3或r4,r5,r5或任何您想要的宏参数,程序集就会将作为参数给出的寄存器替换为宏体。

答案 1 :(得分:0)

您可以使用宏:

.macro multiply A B C
{body}
.endm

\A, \B, \C

可提供正文中参数的值

你的代码中有一点错误:

Multiply:
    stmfd   sp!,{r0-r2, lr}
    mov R2, #1
    mov R3, #0 
    repeat:
        add R3, R1, R3  
        add R2, R2, #1
        cmp R2, R0
        ble repeat
    mov R2, R3
    LDMFD   sp!,{r0-r1, pc}

当R0为0时,结果将是R1而不是0.所以你必须在它进入循环之前检查它。正确的代码是:

stmfd   sp!,{r0-r2, lr}
mov R2, #0
mov R3, #0 
repeat:
    cmp R2, R0
    be exit_loop
    add R3, R1, R3  
    add R2, R2, #1
    b repeat
exit_loop:
mov R2, R3
LDMFD   sp!,{r0-r1, pc}

但这不是最优的方法,因为循环体中有5个指令而不是4个,而2个分支而不是1个,因此很难预测它们。这就是为什么我们要做以下事情:

stmfd   sp!,{r0-r2, lr}
mov R2, #-1
rsb R3, R1, #0 
repeat:
    add R3, R1, R3  
    add R2, R2, #1
    cmp R2, R0
    bne repeat
mov R2, R3
LDMFD   sp!,{r0-r1, pc}

最后,对于宏,它将如下所示:

.macro multiply C B A
stmfd   sp!,{\A, \B, \C, r2, lr}
mov R2, #-1
rsb \C, \B, #0 
repeat:
    add \C, \B, \C  
    add R2, R2, #1
    cmp R2, \A
    bne repeat
LDMFD   sp!,{\A, \B, \C, r2, pc}
.endm

multiply R3 R2 R1 will save the result into R3

但我不知道你为什么要编写自己的乘法宏,我希望你知道,有一套乘法指令......