2016-09-07 68 views
0

对于一类刚刚开始使用ARM汇编语言,我们都需要实现一个简单的for循环如下所述:介绍ARM - 装配误差

h=1; 
for (i=0, i<5, i++) 
    h=(h*3)-i; 

我已经写在ARM汇编下面的代码:

 AREA Prog2, CODE, READONLY 
    ENTRY 

    MOV r0, #1;   initialize h=1 
    MOV r1, #0;   initialize i=0 
loop CMP r1, #5;   at start of loop, compare i with 5 
    MULLT r0, r0, #3; if i<5, h=h*3 
    SUBLT r0, r0, r1; if i<5, h=h-i (ties in with previous line) 
    ADDLT r1, r1, #1; increment i if i is less than 5 
    BLT loop ;   repeat loop of i is less than 5 

stop B stop;    stop program 
    END 

的问题是,有一个与线

 MULLT r0, r0, #3; if i<5, h=h*3 

一个错误。如果我删除它˚F rom代码,一切工作正常。我无法理解这一行的问题。给出的错误描述是“错误的寄存器名称符号,预期的整数寄存器”。我已经尝试将#3加载到寄存器中,然后将这两个寄存器相乘,但这并没有帮助。它只是将错误信息更改为“此寄存器组合导致不可预知的行为。”我是新手,因此请仅提供基本说明以解决此问题。谢谢。

+1

看了你的指令集的引用有什么说的'mul'指令,特别是需要什么操作数的形式。 – Notlikethat

回答

1

MUL要求所有的操作数都是寄存器,所以你必须使用MUL r0, rn, r0的形式,其中rn是其他一些合适的寄存器。

如果结果和第一个操作数相同,则结果是不可预知的,如错误所述。这是由于处理器的内部操作。这就是为什么你必须使用r0, rn, r0而不是r0, r0, rn

+0

快速参考卡没有提到任何限制,除非你试图在Thumb-2上使用muls,否则'Rd'和'Rm'需要相同,否则'muls'不可用。所以,他也可以通过使用第三个寄存器来避开不可预知的行为,但我想这会使程序不必要地复杂化。 – rjp

+0

@rjp Rd和Rm不需要相同;我认为萨米只是保留了原始代码的意图。唯一的限制是,在ARMv6之前,两个输入寄存器_不能相同。 – Notlikethat

1

无论如何,乘以3被高估; ARM可以用一个成语可笑除了做到这一点:

add r0, r0, r0 lsl #1 // r0 = r0 + r0 *2 
+0

如果从'0'到'-4'而不是从'0'到'4',可以使用'mla r0,r0,r2,r1'和'r2 = 3'。我想我有这个数学的权利。 – rjp