-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLab01.asm
More file actions
258 lines (206 loc) · 5.55 KB
/
Copy pathLab01.asm
File metadata and controls
258 lines (206 loc) · 5.55 KB
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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
.ORIG x3000
;--------------------------------------------------------------------------
; Main
;--------------------------------------------------------------------------
; Print the Signed value
LEA R0, Pr1
PUTS
; Set the flag for PrntDec to SIGNED, then print
; the signed value
AND R0, R0, #0
ADD R0, R0, #1
LDI R1, Signed
JSR PrntDec
LEA R0, Newline
PUTS
; Print the Unsigned value:
LEA R0, Pr2
PUTS
; Set the flat for PrntDec to UNSIGNED, then
; print the unsigned value
AND R0, R0, #0
LDI R1, Unsignd
JSR PrntDec
LEA R0, Newline
PUTS
; Print the null-terminated string
LEA R0, Pr3
PUTS
LD R0, String
PUTS
LEA R0, Newline
PUTS
; Print the Linked List:
LEA R0, Pr4
PUTS
; Load the address of the linked list and print
; the list
LD R0, List
JSR PrntList
LEA R0, Newline
PUTS
HALT
Signed .FILL x3500
Unsignd .FILL x3501
String .FILL x3502
List .FILL x4000
Pr1 .STRINGZ "Signed integer: "
Pr2 .STRINGZ "Unsigned integer: "
Pr3 .STRINGZ "String: "
Pr4 .STRINGZ "Linked list: "
Newline .FILL x0A
.FILL x00
PrntList
;-----------------------------------------------------------------------------------
; PrntList - Print a linked list of signed integers
; Input - The address of the first list node in R0
; The list is assumed to consist of two-word nodes. The first word is
; the value to print, the second value is a pointer to the next node.
;-----------------------------------------------------------------------------------
; Save registers
ST R1, PrlR1
ST R2, PrlR2
ST R7, PrlR7
; R2 is a pointer to the current list node
ADD R2, R0, #0
; When the pointer is null, we're done
ADD R2, R2, #0
BRz PrlDone
; R0 is the signed/unsigned flag for PrntDec
PrlLoop AND R0, R0, #0
ADD R0, R0, #1
; Print the current value
LDR R1, R2, #0
JSR PrntDec
; Advance to the next node
LDR R2, R2, #1
; If it is not null, print a separator and continue
ADD R2, R2, #0
BRz PrlDone
LEA R0, SepStr
PUTS
BRnzp PrlLoop
PrlDone LD R1, PrlR1
LD R2, PrlR2
LD R7, PrlR7
RET
PrlR1 .BLKW #1
PrlR2 .BLKW #1
PrlR7 .BLKW #1
SepStr .STRINGZ ", "
DivTen
; ----------------------------------------------------------------------------------
; DivTen - Divide a value by 10, also returning the remainder
; Input - A positive integer in R0
; Output - R0 <- R0 / 10 (integer division); R0 <- R0 Mod 10 (remainder)
; Side Effects - None
; ----------------------------------------------------------------------------------
; Save registers
ST R2, MTR2
ST R3, MTR3
ST R4, MTR4
; R0 will be the remainder. Initial value = the input value.
ADD R0, R1, #0
; R1 will be the result of the integer division. Initial value = 0
AND R1, R1, #0
; Subtract 10 while R0 >= 10
; For each 10 subtracted, add 1 to the result value (in R1)
LD R2, C10 ; R2 <- -10
NOT R2, R2
ADD R2, R2, #1
; If the current value is less than 10, move on
Sub10 ADD R0, R0, #0 ; If the value appears negative, it is > 10
BRn DoSub
ADD R4, R0, R2 ; If it appears positive, check by subtraction
BRzp DoSub
BRnzp DTDONE
; Otherwise subtract 10, and add 1 to result
DoSub ADD R0, R0, R2
ADD R1, R1, #1
BRnzp Sub10
; Restore registers and return
DTDONE LD R2, MTR2
LD R3, MTR3
LD R4, MTR4
RET
; Saved registers
MTR2 .BLKW #1
MTR3 .BLKW #1
MTR4 .BLKW #1
; Constant: 10
C10 .Fill #10
PrntDec
;--------------------------------------------------------------------------------------------------
; PrntDec - Print a 2's complement decimal number to the screen
; Input: A 2's complement integer in R1, and a flag (R0) indicating signed (1) or unsigned (0) in R0
; Return Value: None
; Side Effect: The integer in R1 is printed to the console
;--------------------------------------------------------------------------------------------------
; Save Registers
ST R0, PDR0
ST R1, PDR1
ST R2, PDR2
ST R3, PDR3
ST R4, PDR4
ST R7, PDR7 ; This routine calls another subroutine, so it had better save R7!
; Initialize local register variables
LEA R2, PDBUF ; R2 is a pointer to the print buffer
LD R3, ZERO ; R3 is ASCII Zero
AND R4, R4, #0 ; R4 is a flag: 0=positive, 1=negative
; If the number is unsigned, skip the negative check:
ADD R0, R0, #0
BRz DivLoop
; If the number is negative, note that fact, then invert it
ADD R1, R1, #0
BRzp DivLoop
NOT R1, R1 ; Negate the number
ADD R1, R1, #1
ADD R4, R4, #1 ; Set the R4 flag to negative
DivLoop
; While the value to print is >0, get the low-order decimal digit
; and store in the buffer
; Divide the current number by 10
JSR DivTen
; Convert the remainder to ASCII and store in the buffer
ADD R0, R0, R3 ; Add ASCII 0 (x0030) to convert to a digit
STR R0, R2, #0 ; Save in buffer && ptr++
ADD R2, R2, #1
; If the working value is zero, we have all the digits, so print. Otherwise, repeat.
ADD R1, R1, #0
BRz Print
BRnzp DivLoop
; Back the pointer up one, load the (negated) address of the print buffer into R1
Print ADD R2, R2, #-1
LEA R1, PDBUF
NOT R1, R1
ADD R1, R1, #1
; Print a negative sign if necessary (R4 is the negative flag)
ADD R4, R4, #0
BRz PrLoop
LD R0, NegSign
OUT
; Print the next digit and back up the pointer
PrLoop LDR R0, R2, #0
OUT
ADD R2, R2, #-1
; If the pointer moves beyond the buffer, we're done
ADD R3, R2, R1
BRzp PrLoop
; Restore registers and return
LD R0, PDR0
LD R1, PDR1
LD R2, PDR2
LD R3, PDR3
LD R4, PDR4
LD R7, PDR7
RET
PDR0 .BLKW #1
PDR1 .BLKW #1
PDR2 .BLKW #1
PDR3 .BLKW #1
PDR4 .BLKW #1
PDR7 .BLKW #1
PDBUF .BLKW #7 ; Room for a negative 5 digit number + null
ZERO .FILL x30 ; ASCII zero
NegSign .FILL x2D ; Negative sign: "-"
.END