Using the Stack Frame - ContinuedΒΆ

This more elaborate example has code for two functions, one of which calls the other.

The first function is closeEnough, which has two parameters and two int variables, thus requiring 16 bytes of space in addition to the room for lr and fp:

AddressContents
0xffffffe8diffMagnitude (fp - 20)
0xffffffecdiff (fp - 16)
0xfffffff0y (fp - 12)
0xfffffff4x (fp - 8)
0xfffffff8old fp (for closeEnough's caller) (fp - 4)
0xfffffffclr fp
0x00000000...

The abs function only has one parameter and no local variables, so its stack frame only requires 4 bytes beyond the lr and fp:

AddressContents
0xffffffdcx (fp - 8)
0xffffffe0old fp (for abs's caller) (fp - 4)
0xffffffe4lr fp
0xffffffe8...

As you watch the code run, have both the disassembly and memory panes open so you can pay attention to how the fp (r11) is keeping track of the current stack frame and loads and stores are addressing memory relative to it.

  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
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
.data
a:      .word   25
b:      .word   26

/*
   Main program sets r6 to 1 if a and b are within 1 of each other
   otherwise set r6 to 0

   Calls closeEnough function to help do the job
*/
.text
.global _start
_start:
   @load a and b into "permanent" registers
   LDR   r4, =a
   LDR   r4, [r4]
   LDR   r5, =b
   LDR   r5, [r5]

   @save any r0-r3 I need... (none)
   MOV   r0, r4      @load the parameters
   MOV   r1, r5
   BL    closeEnough
   MOV   r6, r0      @get my return value, store into r6
   @restore any r0-r3... (none)

   @stop program
   end:  B     end
   @exit linux style
   @MOV   r7, #1
   @SWI   0



@----------------------------------------------------------------------
/* CloseEnough - determine if two numbers are within one of each other
   Calls abs to help do the job.

bool closeEnough(int x, int y) {
      int diff = x - y;
      int diffMagnitude = abs(diff);
      return (diffMagnitude <= 1);
}

Params:
r0 = x
r1 = y
Return:
r0 = 1 if within 1, 0 otherwise

Stack Frame:
-------------------------------
FramePointer
Relative
Address           Contents
-------------------------------
-20              diffMagnitude
-16              diff
-12              y
-8               x
-4               old fp
0                my lr
*/
closeEnough:
   @@@ Prologue ----------------------------------------
   PUSH  {fp, lr}          @store my return address and previous fp
                           @If we were going to use r4+ would need to store
                           @sp now points at address 0x04 relative to frame
   ADD   fp, sp, #4        @set fp to point at addres 0x00 relative to frame
   SUB   sp, sp, #16       @Make 16 bytes space for four local variables/parameters
   STR   r0, [fp, #-8]     @store r0 to x in stack frame
   STR   r1, [fp, #-12]    @store r1 to y in stack frame

   @@@ Body --------------------------------------------
   @int diff = x - y;
   LDR   r0, [fp, #-8]     @r0 = x
   LDR   r1, [fp, #-12]    @r1 = y
   SUB   r0, r0, r1        @r0 = x - y
   STR   r0, [fp, #-16]    @store answer to diff in stack frame

   @int diffMagnitude = abs(diff);
   LDR   r0, [fp, #-16]    @get diff into r0
   @save any r0-r3 I care about...none
   BL   abs                @get abs of difference of x and y
   @answer of abs(x - y) is in r0
   @restore any r0-r3 I saved...none
   STR   r0, [fp, #-20]    @store answer to diffMagnitude in stack frame

   @return (diffMagnitude <= 1);
   LDR   r0, [fp, #-20]    @get diffMagnitude into r0
   CMP   r0, #1            @compare diffMagnitude with 1
   MOVLE r0, #1            @set r0 to true/false based on result
   MOVGT r0, #0            @ 1 if diff is <= 1; 0 if diff is > 1

   @@@ Epilog --------------------------------------------
   ADD   sp, sp, #16       @Remove 16 bytes for local variables
   POP   {fp, lr}          @Restore my return address and saved registers
   BX    lr                @return
@----------------------------------------------------------------------


@----------------------------------------------------------------------
/* AbsoluteValue
   Does not call another function

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

Params:
r0 = number
Return:
r0 = |number|

Stack Frame:
-------------------------------
FramePointer
Relative
Address           Contents
-------------------------------
-8               x
-4               old fp
0                my lr
*/
abs:
   @@@ Prologue ----------------------------------------
   PUSH  {fp, lr}          @store previous fp and our lr
                           @If we were going to use r4+ would need to store
   ADD   fp, sp, #4        @set fp to point at addres 0x00 relative to frame
   SUB   sp, sp, #4        @Make 4 bytes space for one local variable/param
   STR   r0, [fp, #-8]     @store r0 to x in stack frame

   @@@ Body --------------------------------------------

   @if (x < 0)
   LDR   r0, [fp, #-8]     @r0 = x
   CMP   r0, #0            @check against 0
   BGE   end_absIf         @if >= 0, skip ahead
   @   x = -x;
   MVN   r0, r0            @was negative, so negate bitwise
   ADD   r0, r0, #1        @add one to get 2's complement negation
   STR   r0, [fp, #-8]     @store back to x in stack frame

end_absIf:
   @@@ Epilog --------------------------------------------
   LDR   r0, [fp, #-8]     @get x into r0
   ADD   sp, sp, #4        @Remove 4 bytes for local variables
   POP   {fp, lr}          @Restore old fp and lr
   BX    lr                @return
@----------------------------------------------------------------------
Try sample
You have attempted of activities on this page