diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-02-17 21:15:27 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-02-17 21:15:27 +0100 |
| commit | 5bceef71ec6e7f8e4e9b7fcb987e44403d6de72c (patch) | |
| tree | 9bd17adb13d10db83cc87cb1dd5d8274b87abeb0 | |
| parent | 62dbebe9528b569d6ba2f843ab4dfa9c80836cf0 (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.hpp | 28 | ||||
| -rw-r--r-- | Private/Toolchain/bin/Source/hello_amd64.masm | 2 | ||||
| -rw-r--r-- | Private/Toolchain/i64asm.cc | 90 |
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 ® : 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++) { |
