7.7. Virtual Functions Sample

Below is the full listing to implement virtual function calls in a code sample designed to emulate the c++ shown on the previous page. Notice that the “constructors” for Parent and Child store the address of the appropriate vtable into the object as it is constructed (lines 141 and 159).

  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
153
154
155
156
157
158
159
160
161
162
163
164
165
.data
/*
Parent structure:
   8 bytes total space
      address - 4 : x
      address + 0 : vtable

VTable:
   0 : Parent_getNum
   4 : Parent_getBigNum
*/

vtable_for_Parent:
   .word   Parent_getNum
   .word   Parent_getBigNum

/*
Child structure:
   12 bytes total space
      address - 8 : y
      address - 4 : Parent.x
      address + 0 : vtable

VTable:
   0 : Child_getNum
   4 : Child_getBigNum
*/

vtable_for_Child:
   .word   Child_getNum
   .word   Child_getBigNum


.text

/*
Translation of:

Parent p1;
Child c1;

Parent* pp1 = &p1;
Parent* pp2 = &c1;

cout << pp1->getNum()    << endl;  //parent version
cout << pp2->getBigNum() << endl;  //child version

Stack in main:
-------------------------------
FramePointer
Relative
Address       Contents
-------------------------------
   -20     = Parent p1
   -8     = Child c1
   -4     = pp2
fp +  0     = pp1

*/

_start:
   @Set FP to bottom of empty space
   SUB   fp, sp, #4
   @Allocate space on the stack for Child, Parent, 2 pointers
   SUB   sp, sp, #28

   @Parent p1
   SUB   r0, fp, #20    @calculate p1's address to r0
   BL    Parent_Parent

   @Child c1
   SUB   r0, fp, #8     @calculate c1's address to r0
   BL    Child_Child

   @pp1 = &p1
   SUB   r0, fp, #20    @calculate p1's address to r0
   STR   r0, [fp]       @store to pp1

   @pp2 = &c1
   SUB   r0, fp, #8     @calculate c1's address to r0
   STR   r0, [fp, #-4]  @store to pp2

   @r4 = pp1->getNum
   LDR   r0, [fp]       @get address from pp1 (&p1)
   LDR   r1, [r0, #0]   @get &p1 + 0 : the vtable
   LDR   r2, [r1, #0]   @get vtable + 0 : getNum
   BLX   r2             @branch with address in r2
   MOV   r4, r0         @store return

   @r5 = pp2->getBigNum
   LDR   r0, [fp, #-4]  @get address from pp2 (&c1)
   LDR   r1, [r0, #0]   @get &c1 + 0 : the vtable
   LDR   r2, [r1, #4]   @get vtable + 4 : getBigNum
   BLX   r2             @branch with address in r2
   MOV   r5, r0         @store return

   ADD   sp, sp, #28    @remove space for local variables

end:
   B     end



/*
Simple implementation - no stack - just return 10
*/
Parent_getNum:
   MOV   r0, #10
   BX    lr

/*
Simple implementation - no stack - just return 100
*/
Parent_getBigNum:
   MOV   r0, #100
   BX    lr


/*
Simple implementation - no stack - just return 5
*/
Child_getNum:
   MOV   r0, #5
   BX    lr

/*
Simple implementation - no stack - just return 5000
*/
Child_getBigNum:
   LDR   r0, =5000
   BX    lr

/*
Simple implementation - no stack
Sets up vtable and initializes x

r0 = this
*/
Parent_Parent:
   @setup vtable at this + 0
   LDR   r1, =vtable_for_Parent  @vtable address
   STR   r1, [r0, #0]            @store to this + 0
   MOV   r1, #1
   STR   r1, [r0, #-4]           @store 1 to this.x (this - 4)
   BX    lr

/*
Simple implementation - only saves lr to stack
Calls parent constructor, then overides vtable and inits y

r0 = this
*/
Child_Child:
   PUSH  {lr}
   @setup parent part of this object
   BL    Parent_Parent

   @change vtable address to be one for Child class
   LDR   r1, =vtable_for_Child   @vtable address
   STR   r1, [r0, #0]            @store to this + 0
   MOV   r1, #2
   STR   r1, [r0, #-8]           @store 2 to this.y (this - 8)

   POP  {lr}
   BX    lr
Try sample
You have attempted of activities on this page