Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Projekt
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Deike, Benedikt
Projekt
Commits
aa08469c
Commit
aa08469c
authored
4 years ago
by
Deike, Benedikt
Browse files
Options
Downloads
Patches
Plain Diff
Upload New File
parent
836caec1
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
Software/Assembler.java
+406
-0
406 additions, 0 deletions
Software/Assembler.java
with
406 additions
and
0 deletions
Software/Assembler.java
0 → 100644
+
406
−
0
View file @
aa08469c
import
java.io.BufferedWriter
;
import
java.io.File
;
import
java.io.FileWriter
;
import
java.io.IOException
;
import
java.math.BigInteger
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Scanner
;
public
class
Assembler
{
private
static
List
<
JumpAddress
>
jumpAddressList
;
private
static
BufferedWriter
writer
;
public
static
void
main
(
String
[]
args
)
throws
IOException
{
File
source
=
new
File
(
args
[
0
]);
Scanner
scannerOne
=
new
Scanner
(
source
);
jumpAddressList
=
new
ArrayList
<
JumpAddress
>
();
int
position
=
0
;
int
address
=
0
;
// TODO : Don't allow the same label twice!
while
(
scannerOne
.
hasNextLine
())
{
String
noComment
=
scannerOne
.
nextLine
().
split
(
"#"
)[
0
];
String
line
[]
=
noComment
.
trim
().
split
(
"\\s+|,\\s+"
);
if
(
line
[
0
].
equals
(
""
))
{
continue
;
}
else
if
(
line
[
0
].
matches
(
"\\w+:$"
))
{
String
labelName
=
line
[
0
].
substring
(
0
,
line
[
0
].
length
()
-
1
);
jumpAddressList
.
add
(
position
,
new
JumpAddress
(
labelName
,
address
*
2
));
position
++;
}
else
{
address
++;
}
}
writer
=
new
BufferedWriter
(
new
FileWriter
(
args
[
1
],
false
));
Scanner
scannerTwo
=
new
Scanner
(
source
);
address
=
0
;
while
(
scannerTwo
.
hasNextLine
())
{
String
noComment
=
scannerTwo
.
nextLine
().
split
(
"#"
)[
0
];
// alternative regular expression: "[\\s,]+"
String
line
[]
=
noComment
.
trim
().
split
(
"\\s+|,\\s+"
);
String
mnemonic
=
line
[
0
];
if
(
mnemonic
.
equals
(
""
))
{
// empty line
continue
;
}
else
if
(
mnemonic
.
matches
(
"[A-Za-z]*:$"
))
{
// line containing a label
continue
;
}
else
{
// line containing an instruction
switch
(
mnemonic
)
{
// -----------------------------------------------------
// -- ALU-Operations -----------------------------------
// -----------------------------------------------------
case
"MOV"
:
writeALUOp
(
"00100000"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"ADDU"
:
writeALUOp
(
"00100001"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"ADDC"
:
writeALUOp
(
"00100010"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"SUBU"
:
writeALUOp
(
"00100011"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"AND"
:
writeALUOp
(
"00100100"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"OR"
:
writeALUOp
(
"00100101"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"XOR"
:
writeALUOp
(
"00100110"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"NOT"
:
writeALUOp
(
"00100111"
,
line
[
1
],
"0000"
);
address
++;
break
;
// -----------------------------------------------------
// -- Shift-Operations ---------------------------------
// -----------------------------------------------------
case
"LSL"
:
writeShiftOp
(
"00101000"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"LSR"
:
writeShiftOp
(
"00101001"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"ASR"
:
writeShiftOp
(
"00101010"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"LSLC"
:
writeShiftOp
(
"00101100"
,
line
[
1
],
"0000"
);
address
++;
break
;
case
"LSRC"
:
writeShiftOp
(
"00101101"
,
line
[
1
],
"0000"
);
address
++;
break
;
case
"ASRC"
:
writeShiftOp
(
"00101110"
,
line
[
1
],
"0000"
);
address
++;
break
;
// -----------------------------------------------------
// -- Compare-Operations -------------------------------
// -----------------------------------------------------
case
"CMPE"
:
writeCompOp
(
"00110000"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"CMPNE"
:
writeCompOp
(
"00110001"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"CMPGT"
:
writeCompOp
(
"00110010"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"CMPLT"
:
writeCompOp
(
"00110011"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
// -----------------------------------------------------
// -- Immediate-Operations -----------------------------
// -----------------------------------------------------
case
"MOVI"
:
writeImmOp
(
"00110100"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"ADDI"
:
writeImmOp
(
"00110101"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"SUBI"
:
writeImmOp
(
"00110110"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"ANDI"
:
writeImmOp
(
"00110111"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"LSLI"
:
writeImmOp
(
"00111000"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"LSRI"
:
writeImmOp
(
"00111001"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"BSETI"
:
writeImmOp
(
"00111010"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
case
"BCLRI"
:
writeImmOp
(
"00111011"
,
line
[
1
],
line
[
2
]);
address
++;
break
;
// -----------------------------------------------------
// -- Memory-Operations --------------------------------
// -----------------------------------------------------
case
"LDW"
:
writeMemOp
(
"0100"
,
line
[
1
],
line
[
2
],
line
[
3
]);
address
++;
break
;
case
"STW"
:
writeMemOp
(
"0101"
,
line
[
1
],
line
[
2
],
line
[
3
]);
address
++;
break
;
// -----------------------------------------------------
// -- Control-Flow-Operations --------------------------
// -----------------------------------------------------
case
"BR"
:
writeControlFlowOp
(
"1000"
,
line
[
1
],
address
);
address
++;
break
;
case
"JSR"
:
writeControlFlowOp
(
"1001"
,
line
[
1
],
address
);
address
++;
break
;
case
"BT"
:
writeControlFlowOp
(
"1010"
,
line
[
1
],
address
);
address
++;
break
;
case
"BF"
:
writeControlFlowOp
(
"1011"
,
line
[
1
],
address
);
address
++;
break
;
case
"JMP"
:
writeJMPOp
(
"1100"
,
line
[
1
]);
address
++;
break
;
// -----------------------------------------------------
// -- Halt ---------------------------------------------
// -----------------------------------------------------
case
"HALT"
:
writeHALTOp
(
"1111"
);
address
++;
break
;
default
:
// TODO: Throw exception, if no mnemonic matched!
}
}
}
writer
.
close
();
scannerTwo
.
close
();
scannerOne
.
close
();
}
public
static
String
regToBin
(
String
register
)
{
String
output
;
switch
(
register
)
{
case
"R0"
:
output
=
"0000"
;
break
;
case
"R1"
:
output
=
"0001"
;
break
;
case
"R2"
:
output
=
"0010"
;
break
;
case
"R3"
:
output
=
"0011"
;
break
;
case
"R4"
:
output
=
"0100"
;
break
;
case
"R5"
:
output
=
"0101"
;
break
;
case
"R6"
:
output
=
"0110"
;
break
;
case
"R7"
:
output
=
"0111"
;
break
;
case
"R8"
:
output
=
"1000"
;
break
;
case
"R9"
:
output
=
"1001"
;
break
;
case
"R10"
:
output
=
"1010"
;
break
;
case
"R11"
:
output
=
"1011"
;
break
;
case
"R12"
:
output
=
"1100"
;
break
;
case
"R13"
:
output
=
"1101"
;
break
;
case
"R14"
:
output
=
"1110"
;
break
;
case
"R15"
:
output
=
"1111"
;
break
;
default
:
// TODO: Throw exception, if no register matched!
output
=
"0000"
;
}
return
output
;
}
public
static
String
hexToBin
(
String
s
)
{
String
hex
=
""
;
if
(
s
.
startsWith
(
"0x"
))
{
hex
=
s
.
substring
(
2
,
s
.
length
());
}
if
(
s
.
startsWith
(
"$"
))
{
hex
=
s
.
substring
(
1
,
s
.
length
());
}
String
bitstring
=
new
BigInteger
(
hex
,
16
).
toString
(
2
);
StringBuffer
extended
=
new
StringBuffer
(
bitstring
);
for
(
int
i
=
bitstring
.
length
();
i
<
4
;
i
++)
{
extended
.
insert
(
0
,
"0"
);
}
return
extended
.
toString
();
}
public
static
void
writeALUOp
(
String
opCo
,
String
rX
,
String
rY
)
throws
IOException
{
writer
.
append
(
opCo
);
writer
.
append
(
regToBin
(
rY
));
writer
.
append
(
regToBin
(
rX
));
writer
.
append
(
"\n"
);
}
public
static
void
writeShiftOp
(
String
opCo
,
String
rX
,
String
rY
)
throws
IOException
{
writer
.
append
(
opCo
);
writer
.
append
(
regToBin
(
rY
));
writer
.
append
(
regToBin
(
rX
));
writer
.
append
(
"\n"
);
}
public
static
void
writeCompOp
(
String
opCo
,
String
rX
,
String
rY
)
throws
IOException
{
writer
.
append
(
opCo
);
writer
.
append
(
regToBin
(
rY
));
writer
.
append
(
regToBin
(
rX
));
writer
.
append
(
"\n"
);
}
public
static
void
writeImmOp
(
String
opCo
,
String
rX
,
String
imm
)
throws
IOException
{
writer
.
append
(
opCo
);
writer
.
append
(
hexToBin
(
imm
));
writer
.
append
(
regToBin
(
rX
));
writer
.
append
(
"\n"
);
}
public
static
void
writeMemOp
(
String
opCo
,
String
rX
,
String
rY
,
String
offsetHex
)
throws
IOException
{
String
offsetBin
=
hexToBin
(
offsetHex
);
int
offsetInt
=
Integer
.
parseInt
(
offsetBin
,
2
);
if
((
offsetInt
%
2
)
==
1
)
{
// TODO: Throw exception, if invalid address is addressed!
}
if
(
offsetInt
>
30
)
{
// TODO: Throw exception, if invalid address is addressed!
}
String
offset
=
offsetBin
.
substring
(
0
,
offsetBin
.
length
()-
1
);
StringBuffer
extended
=
new
StringBuffer
(
offset
);
for
(
int
i
=
offset
.
length
();
i
<
4
;
i
++)
{
extended
.
insert
(
0
,
"0"
);
}
String
jumpAddressBinFixedLength
=
extended
.
toString
();
writer
.
append
(
opCo
);
writer
.
append
(
jumpAddressBinFixedLength
);
writer
.
append
(
regToBin
(
rY
));
writer
.
append
(
regToBin
(
rX
));
writer
.
append
(
"\n"
);
}
// TODO Throw exception, if label is not in jumpAddressList!
public
static
void
writeControlFlowOp
(
String
opCo
,
String
label
,
int
address
)
throws
IOException
{
// PC = PC + 2 + imm12
int
byteAddress
=
2
*
(
address
+
1
);
int
labelAddress
=
0
;
for
(
int
i
=
0
;
i
<
jumpAddressList
.
size
();
i
++)
{
if
(
jumpAddressList
.
get
(
i
).
getLabel
().
equals
(
label
))
{
labelAddress
=
jumpAddressList
.
get
(
i
).
getAddress
();
break
;
}
}
int
jumpAddressInt
=
labelAddress
-
byteAddress
;
String
jumpAddressBin
=
Integer
.
toBinaryString
(
jumpAddressInt
);
String
jumpAddressBinFixedLength
;
if
(
jumpAddressInt
<
0
)
{
jumpAddressBinFixedLength
=
jumpAddressBin
.
substring
(
jumpAddressBin
.
length
()-
12
,
jumpAddressBin
.
length
());
}
else
{
StringBuffer
extended
=
new
StringBuffer
(
jumpAddressBin
);
for
(
int
i
=
jumpAddressBin
.
length
();
i
<
12
;
i
++)
{
extended
.
insert
(
0
,
"0"
);
}
jumpAddressBinFixedLength
=
extended
.
toString
();
}
writer
.
append
(
opCo
);
writer
.
append
(
jumpAddressBinFixedLength
);
writer
.
append
(
"\n"
);
}
public
static
void
writeJMPOp
(
String
opCo
,
String
rX
)
throws
IOException
{
writer
.
append
(
opCo
);
writer
.
append
(
"00000000"
);
writer
.
append
(
regToBin
(
rX
));
writer
.
append
(
"\n"
);
}
public
static
void
writeHALTOp
(
String
opCo
)
throws
IOException
{
writer
.
append
(
opCo
);
writer
.
append
(
"000000000000"
);
writer
.
append
(
"\n"
);
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment