7 Commits

Author SHA1 Message Date
8452b98a97 set c++ standard 2024-10-23 20:51:41 +02:00
3207de80dd parse arguments 2024-10-23 20:48:18 +02:00
39eb113385 add multiple outputs 2024-10-23 20:12:11 +02:00
51f113804a fix jump forward 2024-10-23 20:05:41 +02:00
47e7a17a74 remove compile commands 2024-10-23 11:19:12 +02:00
d3cb3d82de add io file 2024-10-23 11:18:24 +02:00
40041b0f12 clean workspace 2024-10-23 11:13:59 +02:00
12 changed files with 134 additions and 5501581 deletions

2
.gitignore vendored
View File

@@ -5,4 +5,6 @@ build/
# MacOS Cache # MacOS Cache
.DS_Store .DS_Store
.vscode
a.out

View File

@@ -1,11 +1,8 @@
{ {
"configurations": [ "configurations": [
{ {
"name": "Blitz", "name": "Assembleur",
"cppStandard": "c++17", "cppStandard": "c++17",
"includePath": [
"include"
],
"compileCommands": ".vscode/compile_commands.json" "compileCommands": ".vscode/compile_commands.json"
} }
], ],

View File

@@ -1,11 +0,0 @@
[
{
"directory": "/home/simon/Programmation/Assembleur",
"arguments": ["/usr/bin/gcc", "-c", "-m64", "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-O3", "-DNDEBUG", "-o", "build/.objs/Assembleur/linux/x86_64/release/src/main.cpp.o", "src/main.cpp"],
"file": "src/main.cpp"
},
{
"directory": "/home/simon/Programmation/Assembleur",
"arguments": ["/usr/bin/gcc", "-c", "-m64", "-fvisibility=hidden", "-fvisibility-inlines-hidden", "-O3", "-DNDEBUG", "-o", "build/.objs/Assembleur/linux/x86_64/release/src/Assembleur.cpp.o", "src/Assembleur.cpp"],
"file": "src/Assembleur.cpp"
}]

View File

@@ -1,5 +0,0 @@
{
"files.associations": {
"stdexcept": "cpp"
}
}

View File

@@ -78,16 +78,16 @@ std::uint32_t Assembleur::ParseOperationImmediate(
} }
std::uint32_t Assembleur::ParseJump(Instruction a_Instruction, const std::string& a_Label) { std::uint32_t Assembleur::ParseJump(Instruction a_Instruction, const std::string& a_Label) {
int jump = a_Instruction.m_Line - ParseLabel(a_Label); std::int32_t jump = ParseLabel(a_Label) - a_Instruction.m_Line;
if (jump < 0) if (jump < 0)
jump = jump & 0x7FFFFFF | 0x4000000; jump = std::abs(jump) & 0x7FFFFFF | 0x4000000;
return IToInt(a_Instruction) | jump; return IToInt(a_Instruction) | jump;
} }
std::uint32_t Assembleur::ParseJump(Instruction a_Instruction, std::uint8_t a_R1, std::uint8_t a_R2, const std::string& a_Label) { std::uint32_t Assembleur::ParseJump(Instruction a_Instruction, std::uint8_t a_R1, std::uint8_t a_R2, const std::string& a_Label) {
int jump = a_Instruction.m_Line - ParseLabel(a_Label); std::int32_t jump = ParseLabel(a_Label) - a_Instruction.m_Line;
if (jump < 0) if (jump < 0)
jump = jump & 0xFFFFF | 100000; jump = std::abs(jump) & 0xFFFFF | 0x100000;
return IToInt(a_Instruction) | a_R1 << 24 | a_R2 << 21 | jump; return IToInt(a_Instruction) | a_R1 << 24 | a_R2 << 21 | jump;
} }

66
src/IO.cpp Normal file
View File

@@ -0,0 +1,66 @@
#include "IO.h"
#include "Assembleur.h"
#include <bitset>
#include <fstream>
BinaryData ParseFile(const std::string& fileName) {
std::ifstream file{fileName};
std::uint32_t lineNumber = 0, realLineNumber = 0;
std::string currentLine;
std::vector<std::string> lines;
Assembleur assembleur;
BinaryData output;
// parsing labels
while (getline(file, currentLine)) {
lines.push_back(currentLine);
lineNumber++;
realLineNumber++;
if (currentLine.find(":") != std::string::npos) {
std::string label = currentLine.substr(0, currentLine.size() - 1);
assembleur.AddLabel(label, lineNumber);
lineNumber--;
}
}
lineNumber = realLineNumber = 0;
// parsing instructions
for (std::string line : lines) {
lineNumber++;
realLineNumber++;
if (line.find(":") == std::string::npos) {
output.push_back(assembleur.ParseInstruction(line, lineNumber, realLineNumber));
} else {
lineNumber--;
}
}
return output;
}
void OutputFileBinary(const BinaryData& a_Data, const std::string& fileName) {
std::ofstream file{fileName};
file.write(reinterpret_cast<const char*>(a_Data.data()), a_Data.size() * sizeof(a_Data.at(0)));
}
void OutputFileIntegers(const BinaryData& a_Data, const std::string& fileName) {
std::ofstream file{fileName};
for (std::uint32_t number : a_Data) {
file << number << "\n";
}
}
void OutputFileBinIntegers(const BinaryData& a_Data, const std::string& fileName) {
std::ofstream file{fileName};
for (std::uint32_t number : a_Data) {
file << std::bitset<8>(number >> 24) << " " << std::bitset<8>(number >> 16) << " " << std::bitset<8>(number >> 8) <<
" " << std::bitset<8>(number) << "\n";
}
}

12
src/IO.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <vector>
using BinaryData = std::vector<std::uint32_t>;
BinaryData ParseFile(const std::string& fileName);
void OutputFileBinary(const BinaryData& a_Data, const std::string& fileName);
void OutputFileIntegers(const BinaryData& a_Data, const std::string& fileName);
void OutputFileBinIntegers(const BinaryData& a_Data, const std::string& fileName);

View File

@@ -1,49 +1,51 @@
#include <fstream> #include <argparse/argparse.hpp>
#include <iostream> #include <iostream>
#include <vector>
#include "Assembleur.h"
using BinaryData = std::vector<std::uint32_t>;
static BinaryData ParseFile(const std::string& fileName) {
std::ifstream file{fileName};
std::uint32_t lineNumber = 0, realLineNumber = 0;
std::string line;
Assembleur assembleur;
BinaryData output;
while (getline(file, line)) {
lineNumber++;
realLineNumber++;
if (line.find(":") != std::string::npos) {
std::string label = line.substr(0, line.size() - 1);
assembleur.AddLabel(label, lineNumber);
lineNumber--;
} else {
output.push_back(assembleur.ParseInstruction(line, lineNumber, realLineNumber));
}
}
return output;
}
static void OutputFile(const BinaryData& a_Data, const std::string& fileName) {
std::ofstream file {fileName};
file.write(reinterpret_cast<const char*>(a_Data.data()), a_Data.size() * sizeof(a_Data.at(0)));
}
#include "IO.h"
int main(int argc, char** argv) { int main(int argc, char** argv) {
try { argparse::ArgumentParser program("Assembleur");
auto output = ParseFile("test.asm");
std::string inputFileName;
program.add_argument("file")
.help("The assembly file to compile")
.store_into(inputFileName);
std::string outputFileName;
program.add_argument("-o", "--output")
.help("Specify the output file.")
.metavar("file")
.default_value(std::string("a.out"))
.store_into(outputFileName);
std::string formatType;
program.add_argument("-f", "--format")
.help("Type of the output. [bin|int|binint]")
.metavar("type")
.default_value(std::string("binint"))
.choices("bin", "int", "binint")
.store_into(formatType);
try {
program.parse_args(argc, argv);
} catch (const std::exception& err) {
std::cerr << err.what() << std::endl;
std::cerr << program;
std::exit(1);
}
try {
auto output = ParseFile(inputFileName);
if (formatType == "bin") {
OutputFileBinary(output, outputFileName);
} else if (formatType == "int") {
OutputFileIntegers(output, outputFileName);
} else {
OutputFileBinIntegers(output, outputFileName);
}
OutputFile(output, "test.bin");
} catch (std::runtime_error& e) { } catch (std::runtime_error& e) {
std::cerr << e.what() << std::endl; std::cerr << e.what() << std::endl;
return 1; return 1;

View File

@@ -10,11 +10,11 @@ io:
str R1 R2 R3 str R1 R2 R3
ld R1 R2 R3 ld R1 R2 R3
sauts: sauts:
jmp operations jmp controle
jequ R1 R2 io jequ R1 R2 io
jneq R1 R2 sauts jneq R1 R2 sauts
jsup R1 R2 operations jsup R1 R2 operations
jinf R1 R2 io jinf R1 R2 controle
controle: controle:
call io call io
ret ret

BIN
test.bin

Binary file not shown.

5501515
test.txt

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,14 @@
add_rules("mode.debug", "mode.release") add_rules("mode.debug", "mode.release")
add_requires("argparse")
set_languages("c++17")
target("Assembleur") target("Assembleur")
set_kind("binary") set_kind("binary")
add_files("src/*.cpp") add_files("src/*.cpp")
set_rundir(".") set_rundir(".")
add_packages("argparse")
-- --
-- If you want to known more usage about xmake, please see https://xmake.io -- If you want to known more usage about xmake, please see https://xmake.io