diff options
Diffstat (limited to 'asm/intel64/codes.cpp')
-rw-r--r-- | asm/intel64/codes.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/asm/intel64/codes.cpp b/asm/intel64/codes.cpp index a1d9e87..66a08dd 100644 --- a/asm/intel64/codes.cpp +++ b/asm/intel64/codes.cpp @@ -1,7 +1,12 @@ #include "codes.h" +#include <exception> +#include <unordered_map> + +using namespace std::string_literals; + // REX prefix: 0b0100WRXB -std::vector<uint8_t> REX(std::string s) { +std::vector<uint8_t> REX(const std::string& s) { uint8_t result{0b01000000}; if (s == "W") result |= 0b00001000; @@ -15,3 +20,59 @@ std::vector<uint8_t> REX(std::string s) { return { result }; } +namespace { + + std::unordered_map<std::string, size_t> IndexOfRegister{ + {"al", 0}, {"ah", 4}, + {"bl", 3}, {"bh", 7}, + {"cl", 1}, {"ch", 5}, + {"dl", 2}, {"dh", 6}, + + {"ax", 0}, {"sp", 4}, + {"bx", 3}, {"bp", 7}, + {"cx", 1}, {"si", 5}, + {"dx", 2}, {"di", 6}, + + {"eax", 0}, {"esp", 4}, + {"ebx", 3}, {"ebp", 7}, + {"ecx", 1}, {"esi", 5}, + {"edx", 2}, {"edi", 6}, + }; + +} + +// Manual, page 530 +// Reg + Reg/Memory +uint8_t ModRM(const std::string& reg, const std::string& rm) { + // TODO: extend + uint8_t result{0b11000000}; + + auto index1{ IndexOfRegister.find(reg) }; + if (index1 == IndexOfRegister.end()) + throw std::runtime_error("Unknown register for arg1: "s + reg); + + result |= (index1->second << 3); + + auto index2{ IndexOfRegister.find(rm) }; + if (index2 == IndexOfRegister.end()) + throw std::runtime_error("Unknown register for arg2: "s + rm); + + result |= index2->second; + + return result; +} + +#if 0 + prefixes{ + "lock", 0xf0, + + // branch hint + 0x2e, "branch not taken" + 0x3e, "branch taken" + + 0x66, "operand size override" // switch between 16 and 32 bit operands + 0x67, "address size override" // switch between 16 and 32 bit addresses + }; + }; +#endif + |