summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-02-17 21:15:27 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-02-17 21:15:27 +0100
commit5bceef71ec6e7f8e4e9b7fcb987e44403d6de72c (patch)
tree9bd17adb13d10db83cc87cb1dd5d8274b87abeb0
parent62dbebe9528b569d6ba2f843ab4dfa9c80836cf0 (diff)
i64asm: Getting MOD R/M right, also improved assembler.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
-rw-r--r--Private/CompilerKit/AsmKit/Arch/amd64.hpp28
-rw-r--r--Private/Toolchain/bin/Source/hello_amd64.masm2
-rw-r--r--Private/Toolchain/i64asm.cc90
3 files changed, 58 insertions, 62 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
index bb8637f..2438965 100644
--- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp
+++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp
@@ -40,25 +40,25 @@ struct CpuCodeAMD64 {
#define kJumpLimitStandardLimit 0xEB
inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = {
- kAsmOpcodeDecl("int", 0xCD) kAsmOpcodeDecl("into", 0xCE) kAsmOpcodeDecl(
- "intd", 0xF1) kAsmOpcodeDecl("int3", 0xC3)
+kAsmOpcodeDecl("int", 0xCD)
+kAsmOpcodeDecl("into", 0xCE)
+kAsmOpcodeDecl("intd", 0xF1)
+kAsmOpcodeDecl("int3", 0xC3)
- kAsmOpcodeDecl("iret", 0xCF) kAsmOpcodeDecl("retf", 0xCB)
- kAsmOpcodeDecl("retn", 0xC3) kAsmOpcodeDecl("sti", 0xfb)
- kAsmOpcodeDecl("cli", 0xfa)
+kAsmOpcodeDecl("iret", 0xCF)
+kAsmOpcodeDecl("retf", 0xCB)
+kAsmOpcodeDecl("retn", 0xC3)
+kAsmOpcodeDecl("sti", 0xfb)
+kAsmOpcodeDecl("cli", 0xfa)
- kAsmOpcodeDecl("nop", 0x90)
+kAsmOpcodeDecl("nop", 0x90)
- kAsmOpcodeDecl("mov eax", 0xb8) kAsmOpcodeDecl(
- "mov ecx", 0xb9) kAsmOpcodeDecl("mov edx", 0xba)
- kAsmOpcodeDecl("mov ebx", 0xbb) kAsmOpcodeDecl(
- "mov esp", 0xbc) kAsmOpcodeDecl("mov ebp", 0xbd)
- kAsmOpcodeDecl("mov esi", 0xbe)
+kAsmOpcodeDecl("mov", 0x48)
- kAsmOpcodeDecl("jmp", 0xE9)
- kAsmOpcodeDecl("call", 0xE9)
+kAsmOpcodeDecl("jmp", 0xE9)
+kAsmOpcodeDecl("call", 0xFF)
- kAsmOpcodeDecl("mov", 0x00)};
+kAsmOpcodeDecl("mov", 0x00)};
// \brief 64x0 register prefix
// example: r32, r0
diff --git a/Private/Toolchain/bin/Source/hello_amd64.masm b/Private/Toolchain/bin/Source/hello_amd64.masm
index 8ae4f12..2223305 100644
--- a/Private/Toolchain/bin/Source/hello_amd64.masm
+++ b/Private/Toolchain/bin/Source/hello_amd64.masm
@@ -3,7 +3,7 @@ bits 64
export .text MySampleFoo
cli
-mov rsp, rdx
+mov rsp, rsp
int 0x80
jmp 0x100000
sti
diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc
index b86f88a..55719cf 100644
--- a/Private/Toolchain/i64asm.cc
+++ b/Private/Toolchain/i64asm.cc
@@ -982,6 +982,18 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
const std::string &file) {
if (ParserKit::find_word(line, "export ")) return true;
+ struct RegMapAMD64 {
+ std::string fName;
+ e64_byte_t fModRM;
+ };
+
+ std::vector<RegMapAMD64> regsPt2{
+ {.fName = "ax", .fModRM = 0b000}, {.fName = "cx", .fModRM = 0b001},
+ {.fName = "dx", .fModRM = 0b010}, {.fName = "bx", .fModRM = 0b011},
+ {.fName = "sp", .fModRM = 0b100}, {.fName = "bp", .fModRM = 0b101},
+ {.fName = "si", .fModRM = 0b110}, {.fName = "di", .fModRM = 0b111},
+ };
+
for (auto &opcodeAMD64 : kOpcodesAMD64) {
// strict check here
if (ParserKit::find_word(line, opcodeAMD64.fName) &&
@@ -989,21 +1001,9 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
std::string name(opcodeAMD64.fName);
if (name.find("mov") != std::string::npos) {
- struct RegMapAMD64 {
- std::string fName;
- e64_byte_t fModRM;
- };
-
- std::vector<RegMapAMD64> regs{
- {.fName = "ax", .fModRM = 0}, {.fName = "cx", .fModRM = 1},
- {.fName = "dx", .fModRM = 2}, {.fName = "bx", .fModRM = 3},
- {.fName = "sp", .fModRM = 4}, {.fName = "bp", .fModRM = 5},
- {.fName = "si", .fModRM = 6}, {.fName = "di", .fModRM = 7},
- };
-
std::string substr = line.substr(line.find(name) + name.size());
- uint64_t bits = 16;
+ uint64_t bits = 64;
if (substr.find(",") == std::string::npos) {
detail::print_error("Invalid combination of operands and registers.",
@@ -1011,42 +1011,36 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
throw std::runtime_error("comb_op_reg");
}
- bool found = false;
+ bits = 64;
- for (auto &reg : regs) {
- if (line.find(reg.fName) != std::string::npos) {
- if (!found) {
- if (line.substr(line.find(reg.fName) - 1)[0] == 'r') {
- bits = 64;
+ bool noRightRegister = false;
- kBytes.emplace_back(0x48);
- kBytes.emplace_back(0x89);
- kBytes.emplace_back(0x00);
- } else {
- detail::print_error(
- "Invalid combination of registers, each 64-bit register "
- "must start with 'r'.",
- "i64asm");
- throw std::runtime_error("comb_op_reg");
- }
+ if (!noRightRegister) {
+ if (bits == 64 ||
+ bits == 32)
+ {
+ if (bits != 32)
+ kBytes.emplace_back(opcodeAMD64.fOpcode);
- found = true;
+ kBytes.emplace_back(0x89);
- kBytes.push_back(0xc0 + reg.fModRM);
+ // TODO
- continue;
- }
+ this->WriteNumber32(line.find(name) + name.size() + 2, line);
}
- }
+ else if (bits == 16) {
+ kBytes.emplace_back(0x66);
+ kBytes.emplace_back(0x89);
- if (bits == 64)
- this->WriteNumber32(line.find(name) + name.size() + 2, line);
- else if (bits == 16)
- this->WriteNumber16(line.find(name) + name.size() + 2, line);
- else {
- detail::print_error("Invalid combination of operands and registers.",
- "i64asm");
- throw std::runtime_error("comb_op_reg");
+ // TODO
+
+ this->WriteNumber16(line.find(name) + name.size() + 2, line);
+ }
+ else {
+ detail::print_error("Invalid combination of operands and registers.",
+ "i64asm");
+ throw std::runtime_error("comb_op_reg");
+ }
}
break;
@@ -1057,7 +1051,10 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
break;
} else if (name == "jmp" || name == "call") {
kBytes.emplace_back(opcodeAMD64.fOpcode);
- this->WriteNumber32(line.find(name) + name.size() + 1, line);
+
+ if (!this->WriteNumber32(line.find(name) + name.size() + 1, line)) {
+ // TODO
+ }
break;
} else {
@@ -1069,10 +1066,9 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line,
}
}
- if (line.find("db") != std::string::npos) {
- this->WriteNumber(line.find("db") + strlen("db") + 1, line);
- }
- else if (line.find("org ") != std::string::npos) {
+ if (line.find("db ") != std::string::npos) {
+ this->WriteNumber(line.find("db ") + strlen("db ") + 1, line);
+ } else if (line.find("org ") != std::string::npos) {
size_t base[] = {10, 16, 2, 7};
for (size_t i = 0; i < 4; i++) {