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
|
You have attempted of activities on this page