forked from darencard/jekyll-now
-
Notifications
You must be signed in to change notification settings - Fork 0
/
p3_pxs2156.s
243 lines (208 loc) · 9.45 KB
/
p3_pxs2156.s
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
/******************************************************************************
* @file factorial.s
* @brief simple recursion example
*
* Simple example of recursion and stack management
*
* @author Christopher D. McMurrough
******************************************************************************/
.global main
.func main
main:
mainloop:
BL _prompt @ branch to prompt procedure with return
BL _scanf @ branch to scan procedure with return
MOV R1, R0 @ store n, the return value from scanf, in R1
PUSH {R1} @ backup R1
BL _prompt @ branch to prompt procedure with return
BL _scanf @ branch to scan procedure with return
MOV R2, R0 @ store m, the return value from scanf, in R2
PUSH {R2} @ backup register
POP {R2}
MOV R9, R2
POP {R1} @ restore register
MOV R8, R1
BL _int_part @ branch to integer partition procedure w/ return
MOV R1, R8 @ copy return value to R1 for printf
MOV R2, R8
MOV R3, R9
BL _printf @ branch to print procedure with return
B mainloop @ branch to next iteration of the loop
_exit:
MOV R7, #4 @ write syscall, 4
MOV R0, #1 @ output stream to monitor, 1
MOV R2, #21 @ print string length
LDR R1, =exit_str @ string at label exit_str:
SWI 0 @ execute syscall
MOV R7, #1 @ terminate syscall, 1
SWI 0 @ execute syscall
_prompt:
PUSH {R1} @ backup register value
PUSH {R2} @ backup register value
PUSH {R7} @ backup register value
MOV R7, #4 @ write syscall, 4
MOV R0, #1 @ output stream to monitor, 1
MOV R2, #26 @ print string length
LDR R1, =prompt_str @ string at label prompt_str:
SWI 0 @ execute syscall
POP {R7} @ restore register value
POP {R2} @ restore register value
POP {R1} @ restore register value
MOV PC, LR @ return
_printf:
PUSH {LR} @ store the return address
LDR R0, =printf_str @ R0 contains formatted string address
@MOV R1, R1 @ R1 contains printf argument 1 (redundant line)
@MOV R2, R2 @ R2 contains printf argument 2 (redundant line)
BL printf @ call printf
POP {PC} @ restore the stack pointer and return
_scanf:
PUSH {LR} @ store the return address
PUSH {R1} @ backup register value
LDR R0, =format_str @ R0 contains address of format string
SUB SP, SP, #4 @ make room on stack
MOV R1, SP @ move SP to R1 to store entry on stack
BL scanf @ call scanf
LDR R0, [SP] @ load value at SP into R0
ADD SP, SP, #4 @ remove value from stack
POP {R1} @ restore register value
POP {PC} @ restore the stack pointer and return
_int_part:
PUSH {LR}
CMP R1, #0 @ if n == 0, then return 0
MOVEQ R0, #0
POPEQ {PC}
CMP R1,#0
MOVMI R0, #1 @ if n < 0, then return 1
POPMI {PC}
CMP R2, #0 @ if m == 0, then return 0
MOVEQ R0, #0
POPEQ {PC}
PUSH {R1} @ else, backup n
PUSH {R2} @ backup m
SUB R1, R1, R2 @ compute n-m
BL _int_part @ pass (n-m, m) to integer partition
MOV R3, R0 @ store result of int_part in R3
POP {R2} @ restore n
POP {R1} @ restore m
SUB R2, R2, #1 @ compute m-1
BL _int_part @ pass (n, m-1) to integer partition
MOV R4, R0 @ store result of int_part in R4
ADD R0, R3, R4 @ add the results of the calls to int_part
POP {PC} @ return
/******************************************************************************
* @file reg_dump.s
* @brief register print example
*
* Simple example of printing register values to terminal for debugging
*
* @author Christopher D. McMurrough
******************************************************************************/
_reg_dump:
PUSH {LR} @ backup registers
PUSH {R0} @ backup registers
PUSH {R1} @ backup registers
PUSH {R2} @ backup registers
PUSH {R3} @ backup registers
PUSH {R14} @ push registers for printing
PUSH {R13} @ push registers for printing
PUSH {R12} @ push registers for printing
PUSH {R11} @ push registers for printing
PUSH {R10} @ push registers for printing
PUSH {R9} @ push registers for printing
PUSH {R8} @ push registers for printing
PUSH {R7} @ push registers for printing
PUSH {R6} @ push registers for printing
PUSH {R5} @ push registers for printing
PUSH {R4} @ push registers for printing
PUSH {R3} @ push registers for printing
PUSH {R2} @ push registers for printing
PUSH {R1} @ push registers for printing
PUSH {R0} @ push registers for printing
LDR R0,=debug_str @ prepare register print
MOV R1, #0 @ prepare R0 print
POP {R2} @ prepare R0 print
MOV R3, R2 @ prepare R0 print
BL printf @ print R0 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #1 @ prepare R1 print
POP {R2} @ prepare R1 print
MOV R3, R2 @ prepare R1 print
BL printf @ print R1 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #2 @ prepare R2 print
POP {R2} @ prepare R2 print
MOV R3, R2 @ prepare R2 print
BL printf @ print R2 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #3 @ prepare R3 print
POP {R2} @ prepare R3 print
MOV R3, R2 @ prepare R3 print
BL printf @ print R3 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #4 @ prepare R4 print
POP {R2} @ prepare R4 print
MOV R3, R2 @ prepare R4 print
BL printf @ print R4 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #5 @ prepare R5 print
POP {R2} @ prepare R5 print
MOV R3, R2 @ prepare R5 print
BL printf @ print R5 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #6 @ prepare R6 print
POP {R2} @ prepare R6 print
MOV R3, R2 @ prepare R6 print
BL printf @ print R6 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #7 @ prepare R7 print
POP {R2} @ prepare R7 print
MOV R3, R2 @ prepare R7 print
BL printf @ print R7 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #8 @ prepare R8 print
POP {R2} @ prepare R8 print
MOV R3, R2 @ prepare R8 print
BL printf @ print R8 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #9 @ prepare R9 print
POP {R2} @ prepare R9 print
MOV R3, R2 @ prepare R9 print
BL printf @ print R9 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #10 @ prepare R10 print
POP {R2} @ prepare R10 print
MOV R3, R2 @ prepare R10 print
BL printf @ print R10 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #11 @ prepare R11 print
POP {R2} @ prepare R11 print
MOV R3, R2 @ prepare R11 print
BL printf @ print R11 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #12 @ prepare R12 print
POP {R2} @ prepare R12 print
MOV R3, R2 @ prepare R12 print
BL printf @ print R12 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #13 @ prepare R13 print
POP {R2} @ prepare R13 print
MOV R3, R2 @ prepare R13 print
BL printf @ print R13 value prior to reg_dump call
LDR R0,=debug_str @ prepare register print
MOV R1, #14 @ prepare R14 print
POP {R2} @ prepare R14 print
MOV R3, R2 @ prepare R14 print
BL printf @ print R14 value prior to reg_dump call
POP {R3} @ restore register
POP {R2} @ restore register
POP {R1} @ restore register
POP {R0} @ restore regsiter
POP {PC} @ return
.data
number: .word 0
format_str: .asciz "%d"
debug_str: .asciz "R%-2d 0x%08X %011d \n"
prompt_str: .asciz "Enter a positive number: "
printf_str: .asciz "There are %d partitions of %d using integers up to %d\n"
exit_str: .ascii "Terminating program.\n"