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