1

So I've had the following task that needs to be written in ARM Assembly

Please test the subroutine by passing the value of n equals 5. The result should equal 15. If n equals 3, the result is 6.

I was given the corresponding Java code:

  int sum (int n)      
   {          
        int result;          
        if (n == 1)           
            return 1;          
        result = Sum (n‐1) + n;   
        return result;      
    }  

And I have written the following code in ARM Assembly

        NAME main
        PUBLIC main
        SECTION .text: CODE (2)
        THUMB

main
        LDR R4, =0x005          ; Value n
        BL SUM

STOP    B STOP

SUM     
        MOV R1, #0x01
        PUSH {R1, LR}
        ADD R5, R5, R4          ; R5 = result
        CMP R5, #1              ; Compare result to 1
        BEQ ADD1

ADD0
        SUB R4, R4, #1          ; Value n - 1
        CMP R4, #0              ; Compare n to 0        
        BEQ ADD1
        BL SUM

ADD1
        POP {R4, LR}
        BX LR                   ; Branch and exchange instruction set

        END

The code is running fine but I want to know if there could be any slight improvements/shortcuts. I am also a little unsure about the comments but I believe what I have written is correct.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Sikablato
  • 31
  • 4
  • This looks like a question for https://codereview.stackexchange.com/ since you have working code and want feedback on it. Obviously the largest improvement would be to use a different algorithm, like the closed form `n * (n+1) / 2` (there are tricks for doing that without overflow of the product before the `/2`), or at least iteration instead of recursion. Actual recursion in asm sucks compared to a simple loop. – Peter Cordes May 06 '20 at 06:30
  • But yes you could optimize, e.g. using `subs` to set flags from SUB and avoiding a `cmp`. Or a predicated `bl` instead of a conditional `beq` to skip it. – Peter Cordes May 06 '20 at 06:32
  • 1
    Are you sure this works? `CMP R5, #1` appears to be checking for `result == 1`, not `n == 1`. I don't see the point of always pushing `1` (rather than `n`) on function entry, either. Also, the standard ARM calling convention passes integer args in `r0, r1, r2, r3`. You seem to be using R4. – Peter Cordes May 06 '20 at 06:33
  • @PeterCordes This seems to be old-school Thumb code, so a predicated `bl` isn't possible AFAIK. – Michael May 06 '20 at 06:43
  • 1
    Note that your code depends on `R5` being zero when your program starts, since you don't initialize it yourself. – Michael May 06 '20 at 06:43
  • what is a predicated bl? this code is fine for thumb at or after armv5t the pop lr cant change modes like bx lr (speaking of you either pop lr or you pop into something else and bx that something else. – old_timer May 06 '20 at 13:55
  • @old_timer Predicated as in “has a condition field valued other than `AL`.” Predicated execution only existed only for selected few instructions in Thumb code before Thumb2 introduced the `IT` mechanism. – fuz May 06 '20 at 13:59
  • use one of r1-r3 instead of r4, r5, although this appears to be standalone so perhaps it doesnt matter. no reason to initialize the fill register to align the stack on the push just use a register unless this is a chip sim and then this makes sense, but do it outside the loop (you would have initialized r5 too if this were the case, so I assume it isnt). If you do this right no reason for the r4 equals to zero check. something feels wrong about your recursion, pondering....push {r1,lr} and pop in reverse no bx or pop say r1,r2 then bx r2 (the larger of the two you use) – old_timer May 06 '20 at 14:03
  • @fuz I dont see a predicated bl...maybe there was an edit. – old_timer May 06 '20 at 14:03
  • only a readability thing but for thumb add r5,r5,r4 equals add r5,r4 no need to show all three unless you want the thumb2 extensions which you shouldnt get doing it this way. same for the subtract. – old_timer May 06 '20 at 14:04
  • okay ran it through a simulator which was easier than pencil and paper the stack pointer is left where it started when returning to the top before stop. so the recursion is fine. and r5 has 15 in it which you probably also knew... – old_timer May 06 '20 at 14:26

0 Answers0