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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
.globl map
.data
arrays: .word 5, 6, 7, 8, 9
.word 1, 2, 3, 4, 7
.word 5, 2, 7, 4, 3
.word 1, 6, 3, 8, 4
.word 5, 2, 7, 8, 1
start_msg: .asciiz "Lists before: \n"
end_msg: .asciiz "Lists after: \n"
.text
main:
jal create_default_list
mv s0, a0 # v0 = s0 is head of node list
#print "lists before: "
la a1, start_msg
li a0, 4
ecall
#print the list
add a0, s0, x0
jal print_list
# print a newline
jal print_newline
# issue the map call
add a0, s0, x0 # load the address of the first node into a0
la a1, mystery # load the address of the function into a1
jal map
# print "lists after: "
la a1, end_msg
li a0, 4
ecall
# print the list
add a0, s0, x0
jal print_list
li a0, 10
ecall
map:
addi sp, sp, -12
sw ra, 0(sp)
sw s1, 4(sp)
sw s0, 8(sp)
beq a0, x0, done # if we were given a null pointer, we're done.
add s0, a0, x0 # save address of this node in s0
add s1, a1, x0 # save address of function in s1
add t0, x0, x0 # t0 is a counter
# remember that each node is 12 bytes long:
# - 4 for the array pointer
# - 4 for the size of the array
# - 4 more for the pointer to the next node
# also keep in mind that we should not make ANY assumption on which registers
# are modified by the callees, even when we know the content inside the functions
# we call. this is to enforce the abstraction barrier of calling convention.
mapLoop:
#add t1, s0, x0 #deleted code
lw t1, 0(s0) # added code : load the address of the array of current node into t1
lw t2, 4(s0) # load the size of the node's array into t2
slli t3,t0,2 # added code
add t1, t1, t3 # offset the array address by the count
lw a0, 0(t1) # load the value at that address into a0
addi sp, sp, -8 # added code
sw t1 ,0(sp) # added code
sw t2 ,4(sp) # added code
jalr s1 # call the function on that value.
lw t2, 4(sp) # added code
lw t1, 0(sp) # added code
addi sp, sp, 8 # added code
sw a0, 0(t1) # store the returned value back into the array
addi t0, t0, 1 # increment the count
bne t0, t2, mapLoop # repeat if we haven't reached the array size yet
#la a0, 8(s0) # error code
lw a0, 8(s0) # added code : load the address of the next node into a0
#lw a1, 0(s1) # deleted code
add a1,s1,x0 # added code : put the address of the function back into a1 to prepare for the recursion
jal ra,map # modified code:recurse
done:
lw s0, 8(sp)
lw s1, 4(sp)
lw ra, 0(sp)
addi sp, sp, 12
jr ra
mystery:
mul t1, a0, a0
add a0, t1, a0
jr ra
create_default_list:
addi sp, sp, -4
sw ra, 0(sp)
li s0, 0 # pointer to the last node we handled
li s1, 0 # number of nodes handled
li s2, 5 # size
la s3, arrays
loop: #do...
li a0, 12
jal malloc # get memory for the next node
mv s4, a0
li a0, 20
jal malloc # get memory for this array
sw a0, 0(s4) # node->arr = malloc
lw a0, 0(s4)
mv a1, s3
jal fillArray # copy ints over to node->arr
sw s2, 4(s4) # node->size = size (4)
sw s0, 8(s4) # node-> next = previously created node
add s0, x0, s4 # last = node
addi s1, s1, 1 # i++
addi s3, s3, 20 # s3 points at next set of ints
li t6 5
bne s1, t6, loop # ... while i!= 5
mv a0, s4
lw ra, 0(sp)
addi sp, sp, 4
jr ra
fillArray: lw t0, 0(a1) #t0 gets array element
sw t0, 0(a0) #node->arr gets array element
lw t0, 4(a1)
sw t0, 4(a0)
lw t0, 8(a1)
sw t0, 8(a0)
lw t0, 12(a1)
sw t0, 12(a0)
lw t0, 16(a1)
sw t0, 16(a0)
jr ra
print_list:
bne a0, x0, printMeAndRecurse
jr ra # nothing to print
printMeAndRecurse:
mv t0, a0 # t0 gets address of current node
lw t3, 0(a0) # t3 gets array of current node
li t1, 0 # t1 is index into array
printLoop:
slli t2, t1, 2
add t4, t3, t2
lw a1, 0(t4) # a0 gets value in current node's array at index t1
li a0, 1 # preparte for print integer ecall
ecall
li a1, ' ' # a0 gets address of string containing space
li a0, 11 # prepare for print string ecall
ecall
addi t1, t1, 1
li t6 5
bne t1, t6, printLoop # ... while i!= 5
li a1, '\n'
li a0, 11
ecall
lw a0, 8(t0) # a0 gets address of next node
j print_list # recurse. We don't have to use jal because we already have where we want to return to in ra
print_newline:
li a1, '\n'
li a0, 11
ecall
jr ra
malloc:
mv a1, a0 # Move a0 into a1 so that we can do the syscall correctly
li a0, 9
ecall
jr ra
|