diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-28 09:58:23 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2024-01-28 09:58:23 +0100 |
| commit | f08280eb5759350b2bc22a0ae901184ffc7bd80f (patch) | |
| tree | 99d0690559b3a7176d4fcb920023e03d37ff1839 | |
| parent | 73482b5dd2f8bacc019c8db2a563f45f81961686 (diff) | |
Asm: Improved AMD64 support for i64asm.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
| -rw-r--r-- | Private/CompilerKit/AsmKit/Arch/amd64.hpp | 14 | ||||
| -rw-r--r-- | Private/CompilerKit/AsmKit/AsmKit.hpp | 69 | ||||
| -rw-r--r-- | Private/Toolchain/64asm.cc | 15 | ||||
| -rw-r--r-- | Private/Toolchain/bin/Source/hello_amd64.masm | 8 | ||||
| -rw-r--r-- | Private/Toolchain/i64asm.cc | 601 | ||||
| -rw-r--r-- | Public/PDF/ASM_86.TXT | 1 |
6 files changed, 613 insertions, 95 deletions
diff --git a/Private/CompilerKit/AsmKit/Arch/amd64.hpp b/Private/CompilerKit/AsmKit/Arch/amd64.hpp index 239bdca..ac92c9b 100644 --- a/Private/CompilerKit/AsmKit/Arch/amd64.hpp +++ b/Private/CompilerKit/AsmKit/Arch/amd64.hpp @@ -45,12 +45,19 @@ struct CpuCodeAMD64 #define kJumpLimitStandardLimit 0xEB inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = { - kAsmOpcodeDecl("int", 0xE3) + kAsmOpcodeDecl("int", 0xCD) kAsmOpcodeDecl("into", 0xCE) + kAsmOpcodeDecl("intd", 0xF1) + kAsmOpcodeDecl("int3", 0xC3) + kAsmOpcodeDecl("iret", 0xCF) - kAsmOpcodeDecl("ret", 0xC3) + kAsmOpcodeDecl("retf", 0xCB) + kAsmOpcodeDecl("retn", 0xC3) kAsmOpcodeDecl("sti", 0xfb) kAsmOpcodeDecl("cli", 0xfa) + + kAsmOpcodeDecl("nop", 0x90) + kAsmOpcodeDecl("mov eax", 0xb8) kAsmOpcodeDecl("mov ecx", 0xb9) kAsmOpcodeDecl("mov edx", 0xba) @@ -58,8 +65,11 @@ inline std::vector<CpuCodeAMD64> kOpcodesAMD64 = { kAsmOpcodeDecl("mov esp", 0xbc) kAsmOpcodeDecl("mov ebp", 0xbd) kAsmOpcodeDecl("mov esi", 0xbe) + kAsmOpcodeDecl("jmp", 0xE9) kAsmOpcodeDecl("call", 0xE9) + + kAsmOpcodeDecl("mov", 0x00) }; // \brief 64x0 register prefix diff --git a/Private/CompilerKit/AsmKit/AsmKit.hpp b/Private/CompilerKit/AsmKit/AsmKit.hpp index cc8940e..a561aad 100644 --- a/Private/CompilerKit/AsmKit/AsmKit.hpp +++ b/Private/CompilerKit/AsmKit/AsmKit.hpp @@ -61,6 +61,53 @@ namespace CompilerKit }; + union NumberCastBase + { + NumberCastBase() = default; + ~NumberCastBase() = default; + + }; + + union NumberCast64 final + { + NumberCast64() = default; + explicit NumberCast64(UInt64 raw) : raw(raw) {} + ~NumberCast64() { raw = 0; } + + CharType number[8]; + UInt64 raw; + }; + + union NumberCast32 final + { + NumberCast32() = default; + explicit NumberCast32(UInt32 raw) : raw(raw) {} + ~NumberCast32() { raw = 0; } + + CharType number[4]; + UInt32 raw; + }; + + union NumberCast16 final + { + NumberCast16() = default; + explicit NumberCast16(UInt16 raw) : raw(raw) {} + ~NumberCast16() { raw = 0; } + + CharType number[2]; + UInt16 raw; + }; + + union NumberCast8 final + { + NumberCast8() = default; + explicit NumberCast8(UInt8 raw) : raw(raw) {} + ~NumberCast8() { raw = 0; } + + CharType number; + UInt8 raw; + }; + class PlatformAssembler { public: @@ -89,6 +136,10 @@ namespace CompilerKit virtual bool WriteLine(std::string &line, const std::string &file) override; virtual bool WriteNumber(const std::size_t& pos, std::string& from_what) override; + virtual bool WriteNumber16(const std::size_t& pos, std::string& from_what); + virtual bool WriteNumber32(const std::size_t& pos, std::string& from_what); + virtual bool WriteNumber8(const std::size_t& pos, std::string& from_what); + }; #endif // __ASM_NEED_AMD64__ @@ -128,23 +179,5 @@ namespace CompilerKit }; #endif // __ASM_NEED_32x0__ - - union NumberCast final - { - explicit NumberCast(UInt64 raw) : raw(raw) {} - ~NumberCast() { raw = 0; } - - CharType number[8]; - UInt64 raw; - }; - - union NumberCast32 final - { - explicit NumberCast32(UInt32 raw) : raw(raw) {} - ~NumberCast32() { raw = 0; } - - CharType number[4]; - UInt32 raw; - }; } diff --git a/Private/Toolchain/64asm.cc b/Private/Toolchain/64asm.cc index 3bd0eda..2764bf0 100644 --- a/Private/Toolchain/64asm.cc +++ b/Private/Toolchain/64asm.cc @@ -309,10 +309,7 @@ MPCC_MODULE(MPUXAssembler64000) // byte from byte, we write this. for (auto& byte : kBytes) { - for (size_t i = 0; i < sizeof(byte); i++) - { - file_ptr_out << reinterpret_cast<const char*>(&byte)[i]; - } + file_ptr_out.write(reinterpret_cast<const char*>(&byte), sizeof(byte)); } if (kVerbose) @@ -662,7 +659,7 @@ bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos, std } } - CompilerKit::NumberCast num(strtoq(jump_label.substr(pos + 2).c_str(), + CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 16)); for (char &i : num.number) @@ -690,7 +687,7 @@ bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos, std } } - CompilerKit::NumberCast num(strtoq(jump_label.substr(pos + 2).c_str(), + CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 2)); if (kVerbose) @@ -718,7 +715,7 @@ bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos, std } } - CompilerKit::NumberCast num(strtoq(jump_label.substr(pos + 2).c_str(), + CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos + 2).c_str(), nullptr, 7)); if (kVerbose) @@ -750,7 +747,7 @@ bool CompilerKit::PlatformAssembler64x0::WriteNumber(const std::size_t &pos, std } } - CompilerKit::NumberCast num(strtoq(jump_label.substr(pos).c_str(), + CompilerKit::NumberCast64 num(strtoq(jump_label.substr(pos).c_str(), nullptr, 10)); for (char &i : num.number) @@ -1017,7 +1014,7 @@ bool CompilerKit::PlatformAssembler64x0::WriteLine(std::string &line, const std: << std::endl; } - CompilerKit::NumberCast num(label.second); + CompilerKit::NumberCast64 num(label.second); for (auto &num : num.number) { diff --git a/Private/Toolchain/bin/Source/hello_amd64.masm b/Private/Toolchain/bin/Source/hello_amd64.masm index 84010aa..0e79a99 100644 --- a/Private/Toolchain/bin/Source/hello_amd64.masm +++ b/Private/Toolchain/bin/Source/hello_amd64.masm @@ -3,5 +3,9 @@ bits 64 export .text MySampleFoo cli -mov edx, 0x1000 -ret
\ No newline at end of file +mov rsp, rdx +int 0x80 +jmp 0x100000 +sti +retf + diff --git a/Private/Toolchain/i64asm.cc b/Private/Toolchain/i64asm.cc index 7ebe06c..f23c3e9 100644 --- a/Private/Toolchain/i64asm.cc +++ b/Private/Toolchain/i64asm.cc @@ -642,109 +642,381 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteNumber(const std::size_t &pos, st switch (jump_label[pos + 1]) { - case 'x': - { - if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), - nullptr, 16); - !res) + case 'x': { - if (errno != 0) + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16); + !res) + { + if (errno != 0) + { + detail::print_error("invalid hex number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_hex"); + } + } + + CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16)); + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + if (kVerbose) { - detail::print_error("invalid hex number: " + jump_label, "i64asm"); - throw std::runtime_error("invalid_hex"); + kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n"; } + + return true; } + case 'b': + { + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2); + !res) + { + if (errno != 0) + { + detail::print_error("invalid binary number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_bin"); + } + } + + CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n"; + } - CompilerKit::NumberCast32 num(strtoq(jump_label.substr(pos + 2).c_str(), - nullptr, 16)); + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; - for (char &i : num.number) + kBytes.push_back(i); + } + + return true; + } + case 'o': { - if (i == 0) - i = 0xFF; + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7); + !res) + { + if (errno != 0) + { + detail::print_error("invalid octal number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_octal"); + } + } - kBytes.push_back(i); + CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n"; + } + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + return true; } + default: + { + break; + } + } - if (kVerbose) + /* check for errno and stuff like that */ + if (auto res = strtoq(jump_label.substr(pos).c_str(), + nullptr, 10); + !res) + { + if (errno != 0) { - kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n"; + return false; } + } - return true; + CompilerKit::NumberCast64 num = CompilerKit::NumberCast64(strtoq(jump_label.substr(pos).c_str(), + nullptr, 10)); + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); } - case 'b': + + if (kVerbose) { - if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), - nullptr, 2); - !res) + kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n"; + } + + return true; +} + +bool CompilerKit::PlatformAssemblerAMD64::WriteNumber32(const std::size_t &pos, std::string &jump_label) +{ + if (!isdigit(jump_label[pos])) + return false; + + switch (jump_label[pos + 1]) + { + case 'x': { - if (errno != 0) + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16); + !res) { - detail::print_error("invalid binary number: " + jump_label, "i64asm"); - throw std::runtime_error("invalid_bin"); + if (errno != 0) + { + detail::print_error("invalid hex number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_hex"); + } } - } - CompilerKit::NumberCast32 num(strtoq(jump_label.substr(pos + 2).c_str(), - nullptr, 2)); + CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16)); - if (kVerbose) + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + if (kVerbose) + { + kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n"; + } + + return true; + } + case 'b': { - kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n"; + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2); + !res) + { + if (errno != 0) + { + detail::print_error("invalid binary number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_bin"); + } + } + + CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n"; + } + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + return true; } + case 'o': + { + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7); + !res) + { + if (errno != 0) + { + detail::print_error("invalid octal number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_octal"); + } + } + + CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7)); - for (char &i : num.number) + if (kVerbose) + { + kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n"; + } + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + return true; + } + default: { - if (i == 0) - i = 0xFF; + break; + } + } - kBytes.push_back(i); + /* check for errno and stuff like that */ + if (auto res = strtoq(jump_label.substr(pos).c_str(), + nullptr, 10); + !res) + { + if (errno != 0) + { + return false; } + } - return true; + CompilerKit::NumberCast32 num = CompilerKit::NumberCast32(strtoq(jump_label.substr(pos).c_str(), + nullptr, 10)); + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); } - case 'o': + + if (kVerbose) { - if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), - nullptr, 7); - !res) + kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n"; + } + + return true; +} + +bool CompilerKit::PlatformAssemblerAMD64::WriteNumber16(const std::size_t &pos, std::string &jump_label) +{ + if (!isdigit(jump_label[pos])) + return false; + + switch (jump_label[pos + 1]) + { + case 'x': { - if (errno != 0) + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16); + !res) { - detail::print_error("invalid octal number: " + jump_label, "i64asm"); - throw std::runtime_error("invalid_octal"); + if (errno != 0) + { + detail::print_error("invalid hex number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_hex"); + } } - } - CompilerKit::NumberCast32 num(strtoq(jump_label.substr(pos + 2).c_str(), - nullptr, 7)); + CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16)); - if (kVerbose) - { - kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n"; - } + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } - for (char &i : num.number) + if (kVerbose) + { + kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n"; + } + + return true; + } + case 'b': { - if (i == 0) - i = 0xFF; + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2); + !res) + { + if (errno != 0) + { + detail::print_error("invalid binary number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_bin"); + } + } + + CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n"; + } - kBytes.push_back(i); + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + return true; } + case 'o': + { + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7); + !res) + { + if (errno != 0) + { + detail::print_error("invalid octal number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_octal"); + } + } - return true; - } - default: - { - break; - } + CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n"; + } + + for (char &i : num.number) + { + if (i == 0) + i = 0xFF; + + kBytes.push_back(i); + } + + return true; + } + default: + { + break; + } } /* check for errno and stuff like that */ if (auto res = strtoq(jump_label.substr(pos).c_str(), nullptr, 10); - !res) + !res) { if (errno != 0) { @@ -752,8 +1024,8 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteNumber(const std::size_t &pos, st } } - CompilerKit::NumberCast32 num(strtoq(jump_label.substr(pos).c_str(), - nullptr, 10)); + CompilerKit::NumberCast16 num = CompilerKit::NumberCast16(strtoq(jump_label.substr(pos).c_str(), + nullptr, 10)); for (char &i : num.number) { @@ -771,6 +1043,118 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteNumber(const std::size_t &pos, st return true; } +bool CompilerKit::PlatformAssemblerAMD64::WriteNumber8(const std::size_t &pos, std::string &jump_label) +{ + if (!isdigit(jump_label[pos])) + return false; + + switch (jump_label[pos + 1]) + { + case 'x': + { + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16); + !res) + { + if (errno != 0) + { + detail::print_error("invalid hex number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_hex"); + } + } + + CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 16)); + + kBytes.push_back(num.number); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 16 number here: " << jump_label.substr(pos) << "\n"; + } + + return true; + } + case 'b': + { + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2); + !res) + { + if (errno != 0) + { + detail::print_error("invalid binary number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_bin"); + } + } + + CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 2)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 2 number here: " << jump_label.substr(pos) << "\n"; + } + + kBytes.push_back(num.number); + + return true; + } + case 'o': + { + if (auto res = strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7); + !res) + { + if (errno != 0) + { + detail::print_error("invalid octal number: " + jump_label, "i64asm"); + throw std::runtime_error("invalid_octal"); + } + } + + CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos + 2).c_str(), + nullptr, 7)); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 8 number here: " << jump_label.substr(pos) << "\n"; + } + + kBytes.push_back(num.number); + + return true; + } + default: + { + break; + } + } + + /* check for errno and stuff like that */ + if (auto res = strtoq(jump_label.substr(pos).c_str(), + nullptr, 10); + !res) + { + if (errno != 0) + { + return false; + } + } + + CompilerKit::NumberCast8 num = CompilerKit::NumberCast8(strtoq(jump_label.substr(pos).c_str(), + nullptr, 10)); + + kBytes.push_back(num.number); + + if (kVerbose) + { + kStdOut << "i64asm: found a base 10 number here: " << jump_label.substr(pos) << "\n"; + } + + return true; +} + ///////////////////////////////////////////////////////////////////////////////////////// // @brief Read and write an instruction to the output array. @@ -790,11 +1174,100 @@ bool CompilerKit::PlatformAssemblerAMD64::WriteLine(std::string &line, const std { std::string name(opcodeAMD64.fName); - kBytes.emplace_back(opcodeAMD64.fOpcode); - if (name.find("mov") != std::string::npos) { - this->WriteNumber(line.find(name) + name.size() + 2, line); + 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; + + if (substr.find(",") == std::string::npos) + { + detail::print_error("Invalid combination of operands and registers.", "i64asm"); + throw std::runtime_error("comb_op_reg"); + } + + bool found = false; + + 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; + + 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"); + } + + found = true; + + kBytes.push_back(0xc0 + reg.fModRM); + + continue; + } + } + } + + 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"); + } + + break; + } + else if (name == "int" || + name == "into" || + name == "intd") + { + kBytes.emplace_back(opcodeAMD64.fOpcode); + this->WriteNumber8(line.find(name) + name.size() + 1, line); + + break; + } + else if (name == "jmp" || + name == "call") + { + kBytes.emplace_back(opcodeAMD64.fOpcode); + this->WriteNumber32(line.find(name) + name.size() + 1, line); + + break; + } + else + { + kBytes.emplace_back(0); + kBytes.emplace_back(opcodeAMD64.fOpcode); + + break; } } } diff --git a/Public/PDF/ASM_86.TXT b/Public/PDF/ASM_86.TXT index b7111be..8669eba 100644 --- a/Public/PDF/ASM_86.TXT +++ b/Public/PDF/ASM_86.TXT @@ -7,4 +7,5 @@ TODO: Encode instructions [ X ] + Fix MOV ModRM [ ] Extend instructions support [ ]
\ No newline at end of file |
