6.6. A Smarter Function CallΒΆ

A lot of time is spent in the previous sample pushing and popping values from the stack. This is necessary because the main part of the program is relying on r1 being maintained and the function is making use of r4 and r5 which it is not supposed to modify. We could do the same work with less saving and restoring by using registers in the way the calling convention expects: temporary work should be done in r0-r3 and values we want to preserve are placed in r4-r9.

This version of the absolute value program uses registers in the way they should. Because it uses r0-r3 for temporaries only and r4-r9 for longer term storage, there is no need to save/restore registers to the stack:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
   Reduces work storing/restoring registers by keeping "local values"
   in r4+
*/

.text
.global _start
_start:
   MOV   r6, #0xAA      @set up some numbers to work with
   MOV   r4, #30
   MOV   r5, #-12

   MOV   r0, r4         @set up parameter for abs call
   BL    abs            @get abs
   MOV   r4, r0         @save result from the function back to r4

   @OK to temporarily use r0-r3 as long as done by next function call
   @Do some random work...
   MOV   r1, #3         @r1 = 3
   MUL   r6, r6, r1     @r6 *= 3
   @done using r1, we are OK if it gets wiped out

   MOV   r0, r5         @setup param
   BL    abs            @get abs
   MOV   r5, r0         @save result back to r5

end:
   B     end            @stop here

@----------------------------------------------------------------------
/*AbsoluteValue

Calculates absolute value of a value passed in via r0.

Avoids taking responsibility for registers by doing all work in r0-r3

int abs(int x) {
   if (x < 0) x = -x;
   return x;
}

Params:
r0 = number
Return:
r0 = |number|
*/
abs:
   @ONLY use registers r0-r3 to do my work
   CMP   r0, #0
   BGE   end_absIf   @check if negative
   MVN   r1, r0      @negative - get bitwise negation
   ADD   r0, r1, #1  @add one to get 2's complement negation

end_absIf:
   @know that r0 now has abs(r0)
   BX    lr          @return
Try sample
You have attempted of activities on this page
Next Section - 6.7. Another Function