-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy patharm.go
157 lines (132 loc) · 3.54 KB
/
arm.go
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
/*
ARMed version 1.0
Author : https://github.com/coderick14
ARMed is a very basic emulator of the ARM instruction set written in Golang
USAGE : ARMed [OPTIONS]... SOURCE_FILE
Example SOURCE_FILE :
ADDI X0, XZR, #3;
BL fact;
B Exit;
fact: SUBI SP, SP, #8;
STUR LR, [SP, #4];
STUR X0, [SP, #0];
SUBIS X9, X0, #1;
B.GE L1;
ADDI X1, XZR, #1;
ADDI SP, SP, #8;
BR LR;
L1: SUBI X0, X0, #1;
BL fact;
LDUR X0, [SP, #0];
LDUR LR, [SP, #4];
ADDI SP, SP, #8;
MUL X1, X0, X1;
BR LR;
Exit:;
--all show all register values after an instruction, with updated ones in color
--end show updated registers only once, at the end of the program. Overrides --all
--no-log suppress logs of statements being executed
--help display help
Found a bug? Feel free to raise an issue on https://github.com/coderick14/ARMed
Contributions welcome :)
*/
package main
import (
"bufio"
"errors"
"flag"
"fmt"
Memory "github.com/coderick14/ARMed/Memory"
"io"
"os"
"strings"
)
const helpString = `ARMed version 1.0
Author : https://github.com/coderick14
ARMed is a very basic emulator of the ARM instruction set written in Golang
USAGE : ARMed [OPTIONS]... SOURCE_FILE
--all show all register values after an instruction, with updated ones in color
--end show updated registers only once, at the end of the program. Overrides --all
--no-log suppress logs of statements being executed
--help display help
Found a bug? Feel free to raise an issue on https://github.com/coderick14/ARMed
Contributions welcome :)`
func main() {
var (
err error
choice string
)
helpPtr := flag.Bool("help", false, "Display help")
allPtr := flag.Bool("all", false, "Display all registers after each instruction")
endPtr := flag.Bool("end", false, "Display registers only at end")
logPtr := flag.Bool("no-log", false, "Suppress log messages")
flag.Parse()
if *helpPtr == true {
fmt.Println(helpString)
return
}
if len(flag.Args()) == 0 {
err = errors.New("Error : Missing filename.\n Type ARMed --help for further help")
fmt.Println(err)
return
}
fileName := flag.Args()[0]
file, err := os.Open(fileName)
if err != nil {
fmt.Println("Error opening file : ", err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
for {
line, err := reader.ReadString(';')
if err == io.EOF {
if len(line) > 1 {
fmt.Println("Missing semicolon near :", line)
return
}
break
} else if err != nil {
fmt.Println("Error while reading file : ", err)
return
}
line = strings.TrimSpace(strings.TrimRight(line, ";"))
if len(line) != 0 {
Memory.InstructionMem.Instructions = append(Memory.InstructionMem.Instructions, line)
}
}
Memory.InitRegisters()
Memory.InstructionMem.ExtractLabels()
if *endPtr == true {
Memory.SaveRegisters()
for Memory.IsValidPC(Memory.InstructionMem.PC) {
if *logPtr == false {
fmt.Println("Executing :", Memory.InstructionMem.Instructions[Memory.InstructionMem.PC])
}
err = Memory.InstructionMem.ValidateAndExecuteInstruction()
if err != nil {
fmt.Println(err)
return
}
}
Memory.ShowRegisters(false)
} else {
for Memory.IsValidPC(Memory.InstructionMem.PC) {
Memory.SaveRegisters()
if *logPtr == false {
fmt.Println("Executing :", Memory.InstructionMem.Instructions[Memory.InstructionMem.PC])
}
err = Memory.InstructionMem.ValidateAndExecuteInstruction()
if err != nil {
fmt.Println(err)
return
}
Memory.ShowRegisters(*allPtr)
fmt.Printf("Continue [Y/n]? : ")
fmt.Scanln(&choice)
if choice == "n" {
break;
}
}
}
}