-
Notifications
You must be signed in to change notification settings - Fork 0
/
p1_tns4616.s
122 lines (108 loc) · 4.81 KB
/
p1_tns4616.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
/******************************************************************************
* @file p1_tns4616.s
* @make a simple calculator that has +,-,*,M
*
* @author Tanmay Sardesai, 1001094616
******************************************************************************/
.global main
.func main
main:
BL _prompt1 @ branch to prompt1 procedure with return
BL _scanf @ branch to scanf procedure with return
MOV R4, R0 @ move return value R0 to argument register R4
BL _prompt2 @ branch to prompt2 procedure with return
BL _getchar @ branch to scanf procedure with return
MOV R5, R0 @ move return value R0 to argument register R5
BL _prompt1 @ branch to prompt1 procedure with return
BL _scanf @ branch to scanf procedure with return
MOV R6, R0 @ move return value R0 to argument register R6
MOV R1,R4 @ move return value R0 to argument register R1
MOV R2,R5 @ move return value R0 to argument register R1
MOV R3,R6 @ move return value R0 to argument register R1
BL _compare @ check the scanf input
MOV R1,R0 @ move result to input register R1 from register R0
BL _print_val @ print value stored in R1
B main @ branch back to start of main for infinite loop
_print_val:
PUSH {LR} @ store LR since printf call overwrites
LDR R0,=result_str @ string at label resultstr:
BL printf @ call printf, where R1 is the print argument
MOV LR, R7 @ restore LR from R4
POP {LR}
MOV PC, LR @ return
_scanf:
PUSH {LR} @ store LR since scanf call overwrites
SUB SP, SP, #4 @ make room on stack
LDR R0, =format_str @ R0 contains address of format string
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 @ restore the stack pointer
POP {LR}
MOV PC, LR @ return
_printf:
PUSH {LR} @ store LR since printf call overwrites
LDR R0, =printf_str @ R0 contains formatted string address
MOV R1, R1 @ R1 contains printf argument (redundant line)
BL printf @ call printf
POP {LR}
MOV PC, LR @ return
_prompt1:
MOV R7, #4 @ write syscall, 4
MOV R0, #1 @ output stream to monitor, 1
MOV R2, #17 @ print string length
LDR R1, =prompt1_str @ string at label prompt_str:
SWI 0 @ execute syscall
MOV PC, LR @ return
_prompt2:
MOV R7, #4 @ write syscall, 4
MOV R0, #1 @ output stream to monitor, 1
MOV R2, #33 @ print string length
LDR R1, =prompt2_str @ string at label prompt_str:
SWI 0 @ execute syscall
MOV PC, LR @ return
_getchar:
MOV R7, #3 @ write syscall, 3
MOV R0, #0 @ input stream from monitor, 0
MOV R2, #1 @ read a single character
LDR R1, =read_char @ store the character in data memory
SWI 0 @ execute the system call
LDR R0, [R1] @ move the character to the return register
AND R0, #0xFF @ mask out all but the lowest 8 bits
MOV PC, LR @ return
_compare:
PUSH {LR}
CMP R2, #'+' @ compare against the constant char '+'
BLEQ _add @ branch if equal to add with return
CMP R2, #'-' @ compare against the constant char '-'
BLEQ _sub @ branch if equal to add with return
CMP R2, #'*' @ compare against the constant char '*'
BLEQ _mul @ branch if equal to add with return
CMP R2, #'M' @ compare against the constant char 'M'
BLEQ _max @ branch if equal to add with return
POP {LR}
MOV PC, LR @ return
_add:
MOV R0,R1 @ copy input register R1 to output R0
ADD R0,R3 @ add input register R3 to register R0
MOV PC,LR @ return
_sub:
MOV R0,R1 @ copy input register R1 to output R0
SUB R0,R3 @ sub input register R3 from register R0
MOV PC,LR @ return
_mul:
MOV R0,R1 @ copy input register R1 to output R0
MUL R0,R3 @ multiply input register R3 to register R0
MOV PC,LR @ return
_max:
CMP R1,R3 @ compare value in register R1, R3
MOVLE R1,R3 @ move register R3 to R1 is R1 is lesser than or equal to R3
MOV R0,R1 @ move from register R1 to output register R0
MOV PC,LR @ return
.data
printf_str: .asciz "The number entered was: %d\n"
format_str: .asciz "%d"
read_char: .ascii " "
prompt1_str: .ascii "Enter a number : "
prompt2_str: .ascii "Enter a operation from +,-,*,M : "
result_str: .asciz "Result = %d\n"