├── .gitignore ├── Makefile ├── new.s ├── README.md ├── LICENSE ├── encoder.py ├── elf.h ├── assembler.c └── opcodes.h /.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !*.c 3 | !*.h 4 | !*.s 5 | !Makefile 6 | !.gitignore 7 | !README.md 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROG=./lass 2 | NDI=ndisasm 3 | 4 | all: compile test 5 | 6 | compile: 7 | gcc -Wall -std=gnu99 assembler.c -o $(PROG) 8 | 9 | clean: 10 | rm *.o 11 | 12 | test: 13 | $(PROG) new.s bin 14 | $(NDI) -b 32 output 15 | -------------------------------------------------------------------------------- /new.s: -------------------------------------------------------------------------------- 1 | bits 32 2 | 3 | ; takes edx as argument 4 | syscall_one: 5 | mov eax, 1 6 | int 0x80 7 | pop ebp 8 | retn 9 | 10 | main: 11 | push ebp 12 | mov ebp, esp 13 | mov edx, .string 14 | jmp syscall_one 15 | 16 | mov eax, [ebp+4] 17 | 18 | .string: 19 | db "HELLO" 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lass - the lightweight assembler 2 | 3 | ### Unmaintained project 4 | 5 | ### lass is a lightweight two-pass x86 assembler written in C with a focus on portability 6 | 7 | lass uses intel syntax, and currently supports nasm style labels (with $ and $$). 8 | 9 | Benefits: 10 | * bare minimum of library calls: strtok, strcmp, strcpy, etc. 11 | * Single C file, one header (+ elf header if you want ELF executables) 12 | * Operates on a char[] buffer, so you can implement whatever kind of input you want 13 | 14 | Drawbacks: 15 | * It's not complete 16 | * Doesn't support full NASM syntax yet (macros, "equ", resb) 17 | 18 | A majority of the intel instruction set is supported, with complete support being the goal. 19 | 20 | ### to-do: 21 | * Fix SIB addressing mode (mov eax, [ebp + eax*2 + 8], etc etc) 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Michael Lazear 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /encoder.py: -------------------------------------------------------------------------------- 1 | #encoder.py 2 | #shout out to x86asm.net for the extremely helpful opcode tables 3 | c = \ 4 | ''' /* This file was generated by encoder.py as part of lass - the lightweight assembler 5 | (C) 2016 Michael Lazear*/ 6 | #ifndef __LASS_ISA__ 7 | #define __LASS_ISA__ 8 | 9 | typedef struct _instruction_set { 10 | char name[10]; 11 | int op1; 12 | int op2; 13 | int primary; 14 | int extension; 15 | int secondary; 16 | int prefix; 17 | } isa; 18 | 19 | #define none 0 20 | #define r32 0x10 21 | #define rm32 r32 22 | #define r8 0x20 23 | #define rm8 r8 24 | #define imm8 0x40 25 | #define imm32 0x80 26 | #define crn 0x100 27 | #define rel8 0x200 28 | #define rel32 0x400 29 | #define eax r32 | EAX | 0x800 // So this value doesn't get used 30 | #define edx r32 | EDX 31 | #define ecx r32 | ECX 32 | #define ebx r32 | EBX 33 | #define sreg 0x1000 34 | #define ss sreg | 2 35 | #define cs sreg | 1 36 | #define ds sreg | 3 37 | #define es sreg | 0 38 | #define fs sreg | 4 39 | #define gs sreg | 5 40 | 41 | ''' 42 | good = ["sreg", "rel8", "rel32", "r8", "r32", "crn", "r16", "rm8", "rm16", "rm32", \ 43 | "imm8", "imm16", "imm32", "eax", "ecx", "edx", "none", "", "ds", "es", "fs", \ 44 | "gs", "cs", "ss", "m"] 45 | bad = ["xmm", "xmm/m128", "mm"] 46 | 47 | not_really_operands = [ "1", "flags", "eflags"] 48 | 49 | 50 | # Things that don't really have operands 51 | white_list = ["stos", "stosb", "stosw", "stosd", "sysenter", "sysexit", "pusha", "popa", "pushad", "popad"] 52 | one_args = ["lidt", "lgdt", "sidt", "sgdt", "div", "mul"] 53 | 54 | with open("opcodes.h", "w") as o: 55 | o.write(c) 56 | with open("opcodes.csv", "r") as f: 57 | o.write("isa x86[] = {\n") 58 | last = [] 59 | for line in f: 60 | line = line.lower() 61 | line = line.replace("r/m", "rm") 62 | line = line.replace("16/32", "32") 63 | line = line.replace("16", "32") 64 | line = line.split(',') 65 | line = ["" if x in not_really_operands else x for x in line] 66 | #print(line) 67 | name = line[0] # instruction name 68 | op1 = line[1] # operand 1 type 69 | op2 = line[2] # operand 2 type 70 | #print(line[3]) 71 | pf = line[6] # extraordinary prefix 72 | of = line[7] # dedicated 0Fh prefix 73 | code = line[8] # preimary opcode 74 | ext = line[10] 75 | if code and code != "po": 76 | if "+r" in code: 77 | op2 = op2 if op2 else "none" 78 | ext = "DEAD" 79 | code = code.split("+")[0] 80 | if ext: 81 | if ext == 'r': 82 | ext = "0x0" 83 | else: 84 | ext = '0x' + ext 85 | else: 86 | ext= "0x0" 87 | 88 | pf = pf if pf else "0" 89 | of = of if of else "0" 90 | 91 | if name in one_args: 92 | print(line) 93 | op1 = "rm32" if "rm32" in line else "rm8" 94 | op2 = "none" 95 | if name in white_list: 96 | op1 = "none" 97 | op2 = "none" 98 | op1 = "none" if op1 == "" else op1 99 | op2 = "none" if op2 == "" else op2 100 | 101 | if "rm" in op1 and "r" in op2 and name != "test": 102 | continue 103 | if op1 in good and op2 in good: 104 | o.write("\t{\"" + name.lower() + "\", " + op1.lower() + ", " + op2.lower() + ", 0x" + code + ", " + ext + ", 0x" + pf + ", 0x" + of + "},\n") 105 | last = [name.lower(), op1, op2, code, ext, pf, of] 106 | 107 | #elif op1 not in bad and op2 not in bad: 108 | # print("\t{\"" + name.lower() + "\", " + op1.lower() + ", " + op2.lower() + ", 0x" + code + ", " + ext + ", 0x" + pf + ", 0x" + of + "}") 109 | else: 110 | print(line) 111 | if last: 112 | last[0] = name 113 | o.write("\t{\"" + last[0] + "\", " + last[1] + ", " + last[2] + ", 0x" + last[3] + ", " + last[4] + ", 0x" + last[5] + ", 0x" + last[6] + "},\n") 114 | 115 | 116 | o.write("};\n#endif") 117 | -------------------------------------------------------------------------------- /elf.h: -------------------------------------------------------------------------------- 1 | /* 2 | elf.h 3 | =============================================================================== 4 | MIT License 5 | Copyright (c) 2007-2016 Michael Lazear 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in all 15 | copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | SOFTWARE. 24 | =============================================================================== 25 | */ 26 | 27 | #include 28 | 29 | #define ELF_MAGIC 0x464C457FU // "\x7FELF" in little endian 30 | 31 | /* e_type definitions */ 32 | #define ET_NONE 0 33 | #define ET_REL 1 // Relocatable file 34 | #define ET_EXEC 2 // Executable 35 | #define ET_DYN 3 // Shared object file 36 | #define ET_CORE 4 // Core file 37 | 38 | #define EM_386 3 // Intel x86 39 | 40 | typedef struct { 41 | uint32_t e_ident[4]; /* Magic number and other info */ 42 | uint16_t e_type; /* Object file type */ 43 | uint16_t e_machine; /* Architecture */ 44 | uint32_t e_version; /* Object file version */ 45 | uint32_t e_entry; /* Entry point virtual address */ 46 | uint32_t e_phoff; /* Program header table file offset */ 47 | uint32_t e_shoff; /* Section header table file offset */ 48 | uint32_t e_flags; /* Processor-specific flags */ 49 | uint16_t e_ehsize; /* ELF header size in bytes */ 50 | uint16_t e_phentsize; /* Program header table entry size */ 51 | uint16_t e_phnum; /* Program header table entry count */ 52 | uint16_t e_shentsize; /* Section header table entry size */ 53 | uint16_t e_shnum; /* Section header table entry count */ 54 | uint16_t e_shstrndx; /* Section header string table index */ 55 | } elf32_ehdr; 56 | 57 | #define SHT_NULL 0 /* inactive */ 58 | #define SHT_PROGBITS 1 /* Program defined */ 59 | #define SHT_SYMTAB 2 /* Symbol table */ 60 | #define SHT_STRTAB 3 /* String table */ 61 | #define SHT_RELA 4 /* Relocation entries Elf32_Rela */ 62 | #define SHT_HASH 5 63 | #define SHT_DYNAMIC 6 64 | #define SHT_NOTE 7 65 | #define SHT_NOBITS 8 /* .bss */ 66 | #define SHT_REL 9 /* Relocation entries Elf32_Rel */ 67 | #define SHT_SHLIB 10 68 | #define SHT_DYNSYM 11 69 | 70 | #define SHF_WRITE 1 /* Writable data */ 71 | #define SHF_ALLOC 2 /* Allocated memory */ 72 | #define SHF_EXEC 4 /* Executable instr */ 73 | 74 | typedef struct { 75 | uint32_t sh_name; /* Index into section header str table */ 76 | uint32_t sh_type; /* Section header type */ 77 | uint32_t sh_flags; 78 | uint32_t sh_addr; /* Address the section should appear at */ 79 | uint32_t sh_offset; /* Offset from first byte in file */ 80 | uint32_t sh_size; 81 | uint32_t sh_link; 82 | uint32_t sh_info; 83 | uint32_t sh_addralign; /* Address alignment constraints */ 84 | uint32_t sh_entsize; 85 | } elf32_shdr; 86 | 87 | typedef struct { 88 | uint32_t p_type; 89 | uint32_t p_offset; /* offset from beginning of file */ 90 | uint32_t p_vaddr; 91 | uint32_t p_paddr; 92 | uint32_t p_filesz; /* bytes of segment in file */ 93 | uint32_t p_memsz; /* bytes of segment in memory */ 94 | uint32_t p_flags; 95 | uint32_t p_align; 96 | } elf32_phdr; 97 | 98 | // table index 0 is reserved 99 | typedef struct { 100 | uint16_t st_name; 101 | uint32_t st_value; 102 | uint16_t st_size; 103 | uint8_t st_info; 104 | uint8_t st_other; 105 | uint16_t st_shndx; 106 | } elf32_sym; 107 | 108 | #define STB_LOCAL 0 109 | #define STB_GLOBAL 1 110 | #define STT_NOTYPE 0 111 | #define STT_OBJECT 1 112 | #define STT_FUNC 2 113 | #define STT_SECTION 3 114 | #define STT_FILE 4 115 | 116 | -------------------------------------------------------------------------------- /assembler.c: -------------------------------------------------------------------------------- 1 | /* 2 | GNU nano 2.7.0 File: LICENSE 3 | 4 | MIT License 5 | 6 | Copyright (c) 2016 Michael Lazear 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | // for linux systems - file IO 37 | #include 38 | 39 | #include "opcodes.h" 40 | #include "elf.h" 41 | 42 | 43 | uint32_t program_length = 0; 44 | uint32_t current_position = 0; 45 | uint32_t num_symbols = 0; 46 | uint32_t unr_symbols = 0; 47 | uint8_t *output; 48 | uint8_t *elf_output; 49 | uint32_t elf_offset = 0; 50 | 51 | int find_symbol(char *label); 52 | 53 | void make_elf() { 54 | printf("Making elf header\n"); 55 | elf_offset = sizeof(elf32_ehdr) + sizeof(elf32_phdr); 56 | elf32_ehdr *e = malloc(sizeof(elf32_ehdr)); 57 | e->e_ident[0] = ELF_MAGIC; 58 | e->e_ident[1] = 0x00010101; 59 | e->e_ident[2] = 0; 60 | e->e_ident[3] = 0; 61 | e->e_type = ET_EXEC; 62 | e->e_machine = 3; 63 | e->e_version = 1; 64 | e->e_entry = find_symbol("main"); 65 | e->e_phoff = sizeof(elf32_ehdr); 66 | e->e_shoff = 0; 67 | e->e_flags = 0; 68 | 69 | e->e_ehsize = sizeof(elf32_ehdr); 70 | e->e_phentsize = sizeof(elf32_phdr) * 1; 71 | e->e_phnum = 1; 72 | e->e_shentsize = 0; 73 | e->e_shnum = 0; 74 | e->e_shstrndx = 0; 75 | 76 | elf32_phdr *p = malloc(sizeof(elf32_phdr)); 77 | p->p_type = 1; 78 | p->p_offset = 0; 79 | p->p_vaddr = 0; 80 | p->p_paddr = 0; 81 | p->p_filesz = program_length + elf_offset; 82 | printf("p_filesz: %d bytes\n", p->p_filesz); 83 | p->p_memsz = p->p_filesz; 84 | p->p_flags = 0x5; 85 | p->p_align = 0x1000; 86 | 87 | elf_output = malloc(elf_offset); 88 | memcpy(elf_output, e, sizeof(elf32_ehdr)); 89 | memcpy(elf_output + sizeof(elf32_ehdr), p, sizeof(elf32_phdr)); 90 | } 91 | 92 | void add_symbol(char *label) { 93 | printf("%08x %s:\n", current_position, label); 94 | for (int i = 0; i < 32 && i < strlen(label); i++) { 95 | symtab[num_symbols].name[i] = label[i]; 96 | } 97 | for (int i = 0; i < unr_symbols; i++) { 98 | if (strncmp(label, unresolved[i].name, strlen(unresolved[i].name)) == 99 | 0) { 100 | /* Added a previously unresolved symbol, so we need to go back and 101 | replace the dummy value with the real label position */ 102 | int dummy = unresolved[i].position; 103 | for (int i = dummy; i < dummy + 4; i += 2) { 104 | uint16_t word = (output[i + 1] << 8 | output[i]); 105 | if (word == dummy) { 106 | output[i] = current_position & 0xFF; 107 | output[i + 1] = (current_position >> 8) & 0xFF; 108 | } 109 | } 110 | } 111 | } 112 | 113 | symtab[num_symbols++].position = current_position; 114 | } 115 | 116 | int find_symbol(char *label) { 117 | for (int i = 0; i < num_symbols; i++) 118 | if (strcmp(symtab[i].name, label) == 0) 119 | return symtab[i].position + elf_offset; 120 | if (strncmp(label, "$$", 2) == 0) 121 | return 0; 122 | if (strcmp(label, "$") == 0) 123 | return current_position + elf_offset; 124 | 125 | unresolved[unr_symbols].position = current_position; 126 | 127 | for (int i = 0; i < 32 && i < strlen(label); i++) 128 | unresolved[unr_symbols].name[i] = label[i]; 129 | unr_symbols++; 130 | return current_position; 131 | } 132 | 133 | /* functions to output in little-endian */ 134 | void write_byte(uint32_t x) { output[current_position++] = x & 0xFF; } 135 | 136 | void write_word(uint32_t x) { 137 | output[current_position++] = x & 0xFF; 138 | output[current_position++] = (x >> 8) & 0xFF; 139 | } 140 | 141 | void write_dword(uint32_t x) { 142 | output[current_position++] = x & 0xFF; 143 | output[current_position++] = (x >> 8) & 0xFF; 144 | output[current_position++] = (x >> 16) & 0xFF; 145 | output[current_position++] = (x >> 24) & 0xFF; 146 | } 147 | 148 | #ifndef __MATH__ 149 | 150 | double log2(double s) { 151 | double i = 0; 152 | while (s /= 2) 153 | i++; 154 | return i; 155 | } 156 | 157 | #endif 158 | 159 | long long lass_atoi(char *s) { 160 | long long num = 0; 161 | int sign = 1; 162 | int base = 10; 163 | char *d = strpbrk(s, "x"); 164 | if (d != NULL) { 165 | base = 16; 166 | s = d + 1; 167 | } 168 | 169 | if (s[0] == '-') 170 | sign = -1; 171 | 172 | for (int i = 0; i < strlen(s) && s[i] != '\0'; i++) { 173 | if (isdigit(s[i])) 174 | num = num * base + (s[i] - '0'); 175 | else if (ishex(s[i])) 176 | num = num * base + (tolower(s[i]) - 'a') + 10; 177 | } 178 | return sign * num; 179 | } 180 | 181 | isa *find_instruction(char *s, int op1, int op2) { 182 | for (int i = 0; i < sizeof(x86) / sizeof(isa); i++) { 183 | if (strcmp(x86[i].name, s) == 0) { 184 | if (op1 & sreg) { 185 | if ((x86[i].op1 == op1) && 186 | ((x86[i].op2 == op2) || (x86[i].op2 == none))) 187 | return &x86[i]; 188 | } else { 189 | if (((x86[i].op1 & op1) == x86[i].op1) && 190 | ((x86[i].op2 == op2) || (x86[i].op2 == none))) 191 | return &x86[i]; 192 | if ((x86[i].op1 == none) && (x86[i].op2 == none)) 193 | return &x86[i]; 194 | } 195 | } 196 | } 197 | /* Second loop - if we have an imm8 or rel8, but there is no designated 198 | imm8/rel8 function, use the 32 bit version. This simply saves some output 199 | space, 200 | and copies the format that NASM uses */ 201 | for (int i = 0; i < sizeof(x86) / sizeof(isa); i++) 202 | if (strcmp(x86[i].name, s) == 0) 203 | if (((x86[i].op1 & op1) == x86[i].op1) && 204 | ((x86[i].op2 & ((op2 & (imm8 | rel8)) ? 0x6C0 : op2)) || 205 | (x86[i].op2 == none))) 206 | return &x86[i]; 207 | return NULL; 208 | } 209 | 210 | /* classify() returns the size of operands and immediates */ 211 | int classify(char *s) { 212 | if (isdigit(*s)) { 213 | long long num = lass_atoi(s); 214 | if (abs(num) > UCHAR_MAX) 215 | return imm32; 216 | else 217 | return imm8; 218 | } 219 | for (int i = 0; i < sizeof(registers) / sizeof(syntax); i++) 220 | if (strcmp(registers[i].name, s) == 0) 221 | return registers[i].code | r32; 222 | for (int i = 0; i < sizeof(half) / sizeof(syntax); i++) 223 | if (strcmp(half[i].name, s) == 0) 224 | return half[i].code | r8; 225 | for (int i = 0; i < sizeof(segments) / sizeof(syntax); i++) 226 | if (strcmp(segments[i].name, s) == 0) { 227 | return segments[i].code | sreg; 228 | } 229 | 230 | return -1; 231 | } 232 | 233 | typedef struct __instruction_s { 234 | int prefix; 235 | int operand; 236 | int modrm; 237 | int sib; 238 | int disp; 239 | } instruction_s; 240 | 241 | instruction_s *calc_sib(char *line, int op1) { 242 | int scale = -1; 243 | int index = -1; 244 | int base = -1; 245 | char *plus = strchr(line, '+'); 246 | char *minus = strchr(line, '-'); 247 | char *star = strchr(line, '*'); 248 | 249 | int c = 0; 250 | int disp = 0; 251 | int mod = 0; 252 | 253 | instruction_s *ret = malloc(sizeof(instruction_s)); 254 | memset(ret, 0, sizeof(instruction_s)); 255 | 256 | /* We haven't been provided the first operand by parse_line. 257 | This should mean that the displacement IS the first operand: 258 | mov [eax+8], ebx etc, etc 259 | */ 260 | if (op1 == 0) { 261 | char *op = strchr(line, ','); 262 | if (op != NULL) { 263 | printf("%s\n", op); 264 | while (*op == ' ' || *op == ',') 265 | op++; 266 | op1 = classify(op); 267 | if (op1 & (imm8 | imm32)) 268 | disp = lass_atoi(op); 269 | } 270 | } 271 | 272 | /* No multiplication symbol, so we assume that no SIB byte is required */ 273 | if (star == NULL) { 274 | scale = 0; 275 | 276 | char *pch = strtok(line, " [+-],"); 277 | while (pch) { 278 | if (isdigit(*pch)) { 279 | disp = lass_atoi(pch); 280 | } else { 281 | if (c == 0) 282 | index = classify(pch) & ~(rm32 | rm8); 283 | if (c == 1) 284 | base = classify(pch); 285 | c++; 286 | } 287 | pch = strtok(NULL, " [+-],*"); 288 | } 289 | 290 | if (disp) { 291 | disp *= (minus) ? -1 : 1; 292 | if (disp > UCHAR_MAX) 293 | ret->modrm = MODRM(MOD_FOUR, (op1 & ~(r8 | r32)), index); 294 | else 295 | ret->modrm = MODRM(MOD_ONE, (op1 & ~(r8 | r32)), index); 296 | ret->disp = disp; 297 | } else { 298 | ret->modrm = MODRM((index == EBP) ? MOD_ONE : MOD_ZERO, 299 | (op1 & ~(r8 | r32)), index); 300 | ret->disp = 0; 301 | } 302 | return ret; 303 | } 304 | 305 | /* We need to calculate an SIB byte 306 | MOD = 00b, 01b, 10b and R/M = 100b */ 307 | char *pch = strtok(line, " [+],*"); 308 | int n; 309 | while (pch) { 310 | if (isdigit(*pch)) { 311 | n = lass_atoi(pch); 312 | 313 | if ((plus < star) && (pch < plus)) { 314 | disp = n; 315 | } 316 | if ((plus plus)) { 317 | scale = n; 318 | } 319 | } else { 320 | if (c == 0) 321 | index = classify(pch); 322 | if (c == 1) 323 | base = classify(pch); 324 | c++; 325 | } 326 | 327 | pch = strtok(NULL, " [+],*"); 328 | } 329 | 330 | /* R/M bits equals 4 always. Mod is determined by SIB addressing mode: 331 | 00 = [reg32 + eax*n] 332 | 01 = [disp + reg8 + eax*n] 333 | 10 = [disp + reg32 + eax*n] 334 | 00 = [disp + eax*n], base field = 101 335 | */ 336 | if (index && base) { 337 | if (index & r32) 338 | mod = 2; 339 | else 340 | mod = 1; 341 | index &= ~(r8 | r32); 342 | base &= ~(r8 | r32); 343 | } 344 | if (base == -1) { 345 | base = 5; 346 | mod = 0; 347 | } 348 | 349 | scale = log2(scale); 350 | 351 | ret->modrm = MODRM(mod, op1, 4); 352 | ret->sib = MODRM(scale, index, base); 353 | ret->disp = disp; 354 | return ret; 355 | } 356 | 357 | void parse_line(char *line, int pass_no) { 358 | if (pass_no > 1) 359 | printf("%08x %-20s\n", current_position, line); 360 | char *displacement = NULL; 361 | char *disp = strpbrk(line, "["); 362 | 363 | if (disp) 364 | displacement = strdup(disp); 365 | 366 | // split line by spaces and commas 367 | char *pch = strtok(line, " ,\t"); 368 | 369 | // store instruction 370 | char *inst; 371 | 372 | uint64_t syn[2] = {0, 0}; 373 | 374 | // number of items in line 375 | int count = 0; 376 | 377 | // store value of immediates 378 | int immediate = 0; 379 | int imm = 0; 380 | 381 | // default to MOD 11b 382 | int mode = MOD_REG; 383 | int m = -1; 384 | int rev = 0; 385 | int sib = 0; 386 | 387 | if (*pch == 'd') { 388 | char next = *(pch + 1); 389 | pch = strtok(NULL, ", '\""); 390 | while (pch) { 391 | switch(next) { 392 | case 'b': { 393 | if (isdigit(*pch)) { 394 | write_byte(lass_atoi(pch)); 395 | } else { 396 | while(*pch) 397 | write_byte(*pch++); 398 | } 399 | break; 400 | } 401 | case 'w': 402 | write_word(lass_atoi(pch)); 403 | break; 404 | case 'd': 405 | write_dword(lass_atoi(pch)); 406 | break; 407 | default: 408 | printf("Unrecognized symbol d%c\n", next); 409 | return; 410 | } 411 | pch = strtok(NULL, ", '\""); 412 | } 413 | return; 414 | } 415 | 416 | while (pch && *pch != ';') { 417 | if (pch == disp && disp) { 418 | // Do something 419 | instruction_s *a = calc_sib(displacement, syn[0]); 420 | m = a->modrm; 421 | sib = a->sib; 422 | immediate = a->disp; 423 | mode = (m >> 6); 424 | 425 | imm = 1; 426 | 427 | syn[1] |= (r32); 428 | if (syn[0] == 0) { 429 | syn[0] = ((m >> 3) & 0x7) | r32; 430 | rev = 1; 431 | } 432 | break; 433 | } 434 | 435 | if (count == 0) { 436 | inst = strdup(pch); 437 | } else { 438 | int n = classify(pch); 439 | 440 | if (n & (imm8 | imm32)) { 441 | imm = 1; 442 | immediate = lass_atoi(pch); 443 | } 444 | // label maybe? 445 | if (n == -1) { 446 | 447 | immediate = find_symbol(pch); 448 | imm = 1; 449 | n = rel8; 450 | } 451 | syn[count - 1] = n; 452 | } 453 | count++; 454 | // get next token 455 | pch = strtok(NULL, " ,\t"); 456 | } 457 | 458 | isa *instruction = find_instruction(inst, syn[0], syn[1]); 459 | 460 | int start = current_position; 461 | 462 | if (instruction) { 463 | int o = instruction->primary; 464 | 465 | // Get any prefixes taken care of 466 | if (instruction->secondary) 467 | write_byte(instruction->secondary); 468 | if (instruction->prefix) 469 | write_byte(0x0F); 470 | 471 | // Two operands 472 | if (syn[1]) { 473 | 474 | if ((syn[0] & (r32 | r8 | sreg)) && (syn[1] & (r32 | r8 | sreg))) 475 | m = (m == -1) ? MODRM(mode, syn[0] &= ~(r32 | r8 | sreg), 476 | syn[1] &= ~(r32 | r8 | sreg)) 477 | : m; 478 | else if ((syn[0] & (r32 | r8)) && 479 | (syn[1] & (imm8 | imm32 | rel8 | rel32))) 480 | m = (m == -1) ? MODRM(mode, instruction->extension, 481 | syn[0] &= ~(r32 | r8)) 482 | : m; 483 | 484 | if ((syn[0] & (imm8 | imm32 | rel8 | rel32))) 485 | m = MODRM(mode, instruction->extension, 0); 486 | 487 | // switch d flag 488 | if (rev) 489 | o ^= 0x2; 490 | 491 | // Macro value for alternate encodings 492 | if (instruction->extension == 0xDEAD) 493 | write_byte(((o & ~0x7) | (syn[0] & ~(r32 | r8)))); 494 | else 495 | write_word(m << 8 | o); 496 | 497 | } else { 498 | // One operand? 499 | if (instruction->extension == 0xDEAD && m == -1) { 500 | write_byte(((o & ~0x7) | (syn[0] & ~(r32 | r8 | sreg)))); 501 | } else { 502 | if (!syn[0]) 503 | write_byte(o); 504 | // Immediate, relative, none or ss/fs/gs/etc 505 | else if (syn[0] & 0x6C0 || (syn[0] & sreg)) 506 | write_byte(o); 507 | else if (syn[0] != none) { 508 | m = (m == -1) ? MODRM(mode, instruction->extension, 509 | syn[0] & ~(r32 | r8 | sreg)) 510 | : m; 511 | write_word(m << 8 | o); 512 | } 513 | } 514 | } 515 | 516 | /* If there's an SIB byte, write it now */ 517 | if (sib) { 518 | write_byte(sib); 519 | } 520 | 521 | if (imm) { 522 | int sw = (instruction->op2 == none) ? instruction->op1 523 | : instruction->op2; 524 | switch (sw) { 525 | case imm8: 526 | write_byte(immediate & 0xFF); 527 | break; 528 | case imm32: 529 | write_dword(immediate); 530 | break; 531 | case rel8: 532 | // Calculate relative offset 533 | write_byte(immediate - current_position - 534 | (current_position - start) - elf_offset); 535 | break; 536 | case rel32: 537 | write_dword(immediate - current_position - 538 | (current_position - start) - elf_offset); 539 | break; 540 | default: 541 | // SIB/Displacement 542 | if (mode == 1) 543 | write_byte(immediate); 544 | else 545 | write_dword(immediate); 546 | } 547 | } 548 | } else { 549 | printf("instruction: %s not recognized?\n", inst); 550 | } 551 | } 552 | 553 | void pass(char *buffer, int sz, int pass_no) { 554 | char **lines = malloc(sz); 555 | 556 | *lines = buffer; 557 | void* start = lines; 558 | 559 | for (int i = 0; i < sz; i++) { 560 | if (buffer[i] == '\n') { 561 | buffer[i] = '\0'; 562 | char *new = buffer + i + 1; 563 | if (*new) 564 | *(lines++) = new; 565 | } 566 | } 567 | 568 | for (lines = start; *lines; lines++) { 569 | if (**lines != ';' && **lines) { // Remove comment-only lines 570 | if (strchr(*lines, ':')) { 571 | char *c = strchr(*lines, ':'); 572 | *c = '\0'; // remove the semi colon 573 | add_symbol(*lines); 574 | } else 575 | parse_line(*lines, pass_no); 576 | } 577 | } 578 | 579 | free(start); 580 | } 581 | 582 | int main(int argc, char *argv[]) { 583 | 584 | if (argc < 2) { 585 | printf("usage: lass input.s\n"); 586 | return -1; 587 | } 588 | char *fname = argv[1]; 589 | 590 | int fp = open(fname, O_RDWR, 0444); 591 | assert(fp); 592 | 593 | // seek to end of file so that we can calculate size 594 | int sz = lseek(fp, 0, SEEK_END); 595 | if (sz < 1) 596 | return -1; 597 | 598 | // Seek back to beginning 599 | lseek(fp, 0, SEEK_SET); 600 | 601 | // Allocate file buffer and read into it 602 | char *buffer = malloc(sz); 603 | output = malloc(sz); 604 | pread(fp, buffer, sz, 0); 605 | 606 | // First pass, generate labels 607 | printf("lass: read %d bytes from %s\n", sz, fname); 608 | printf("First pass, finding labels:\n"); 609 | pass(buffer, sz, 1); 610 | 611 | // Second pass 612 | program_length = current_position; 613 | current_position = 0; 614 | 615 | if (strcmp("elf", argv[2]) == 0) 616 | make_elf(); 617 | pread(fp, buffer, sz, 0); 618 | pass(buffer, sz, 2); 619 | 620 | FILE *fd = fopen("output", "wb"); 621 | assert(fd); 622 | fwrite(elf_output, 1, elf_offset, fd); 623 | fwrite(output, 1, current_position, fd); 624 | fflush(fd); 625 | free(buffer); 626 | printf("Wrote %d bytes to %s\n", current_position, "output"); 627 | 628 | return 0; 629 | } 630 | -------------------------------------------------------------------------------- /opcodes.h: -------------------------------------------------------------------------------- 1 | /* This file was generated by encoder.py as part of lass - the lightweight assembler 2 | (C) 2016 Michael Lazear*/ 3 | #ifndef __LASS_ISA__ 4 | #define __LASS_ISA__ 5 | 6 | 7 | // Mod/RM register codes 8 | #define EAX 0 9 | #define ECX 1 10 | #define EDX 2 11 | #define EBX 3 12 | #define ESP 4 13 | #define EBP 5 14 | #define ESI 6 15 | #define EDI 7 16 | #define sreg 0x1000 17 | #define ss 2 18 | #define cs 1 19 | #define ds 3 20 | #define es 0 21 | #define fs 4 22 | #define gs 5 23 | 24 | /* 25 | Zero: [eax] 26 | One: [eax+ disp8] 27 | Four: [eax+ disp32] 28 | Reg: eax */ 29 | #define MOD_ZERO 0 30 | #define MOD_ONE 1 31 | #define MOD_FOUR 2 32 | #define MOD_REG 3 33 | 34 | #define IMM_OP -2 35 | #define ONE_OP -1 36 | #define COND(a) (COND_##a) 37 | 38 | #define OPCODE(code, sign, width) (code | ((sign & 1)<<1) | (width & 1)) 39 | #define MODRM(mod, reg, rm) ( ((mod & 0x3) << 6)| ((reg & 0x7) << 3) | (rm & 0x7) ) 40 | #define COMBINE(o, m) ( (o<<8) | m) 41 | #define ishex(c) (((tolower(c)) <= 'f') & ((tolower(c)) >= '0')) 42 | #define ENDIAN(x) ( ((x&0xFF) << 24) | ((x&0x0000FF00) << 8) | ((x&0x00FF0000) >> 8) | ((x&0xFF000000) >> 24)) 43 | 44 | struct symbol { 45 | char name[32]; 46 | uint32_t position; 47 | } symtab[256], unresolved[256]; 48 | 49 | typedef struct syntax { 50 | char name[10]; 51 | int code; 52 | 53 | } syntax; 54 | 55 | syntax registers[] = { 56 | { "eax", EAX }, 57 | { "ecx", ECX }, 58 | { "edx", EDX }, 59 | { "ebx", EBX }, 60 | { "esp", ESP }, 61 | { "ebp", EBP }, 62 | { "esi", ESI }, 63 | { "edi", EDI }, 64 | { "ax", EAX }, 65 | { "cx", ECX }, 66 | { "dx", EDX }, 67 | { "bx", EBX }, 68 | { "sp", ESP }, 69 | { "bp", EBP }, 70 | { "si", ESI }, 71 | { "di", EDI }, 72 | }, half[] = { 73 | { "al", EAX }, 74 | { "cl", ECX }, 75 | { "dl", EDX }, 76 | { "bl", EBX }, 77 | { "ah", EAX }, 78 | { "ch", ECX }, 79 | { "dh", EDX }, 80 | { "bh", EBX }, 81 | }, segments[] = { 82 | { "ss", ss }, 83 | { "cs", cs }, 84 | { "es", es }, 85 | { "fs", fs }, 86 | { "gs", gs }, 87 | { "ds", ds }, 88 | }; 89 | 90 | typedef struct _instruction_set { 91 | char name[10]; 92 | int op1; 93 | int op2; 94 | int primary; 95 | int extension; 96 | int secondary; 97 | int prefix; 98 | } isa; 99 | 100 | #define none 0 101 | #define r32 0x10 102 | #define rm32 r32 103 | #define r8 0x20 104 | #define rm8 r8 105 | #define imm8 0x40 106 | #define imm32 0x80 107 | #define crn 0x100 108 | #define rel8 0x200 109 | #define rel32 0x400 110 | #define eax r32 | EAX | 0x800 // So this value doesn't get used 111 | #define edx r32 | EDX 112 | #define ecx r32 | ECX 113 | #define ebx r32 | EBX 114 | #define sreg 0x1000 115 | #define ss sreg | 2 116 | #define cs sreg | 1 117 | #define ds sreg | 3 118 | #define es sreg | 0 119 | #define fs sreg | 4 120 | #define gs sreg | 5 121 | 122 | isa x86[] = { 123 | {"adc", r8, rm8, 0x12, 0x0, 0x0, 0x0}, 124 | {"adc", r32, rm32, 0x13, 0x0, 0x0, 0x0}, 125 | {"adc", eax, imm32, 0x15, 0x0, 0x0, 0x0}, 126 | {"adc", rm8, imm8, 0x80, 0x2, 0x0, 0x0}, 127 | {"adc", rm32, imm32, 0x81, 0x2, 0x0, 0x0}, 128 | {"adc", rm8, imm8, 0x82, 0x2, 0x0, 0x0}, 129 | {"adc", rm32, imm8, 0x83, 0x2, 0x0, 0x0}, 130 | {"add", rm32, imm8, 0x83, 0x2, 0x0, 0x0}, 131 | {"add", r8, rm8, 0x2, 0x0, 0x0, 0x0}, 132 | {"add", r32, rm32, 0x3, 0x0, 0x0, 0x0}, 133 | {"add", eax, imm32, 0x5, 0x0, 0x0, 0x0}, 134 | {"add", rm8, imm8, 0x80, 0x0, 0x0, 0x0}, 135 | {"add", rm32, imm32, 0x81, 0x0, 0x0, 0x0}, 136 | {"add", rm8, imm8, 0x82, 0x0, 0x0, 0x0}, 137 | {"add", rm32, imm8, 0x83, 0x0, 0x0, 0x0}, 138 | {"and", r8, rm8, 0x22, 0x0, 0x0, 0x0}, 139 | {"and", r32, rm32, 0x23, 0x0, 0x0, 0x0}, 140 | {"and", eax, imm32, 0x25, 0x0, 0x0, 0x0}, 141 | {"and", rm8, imm8, 0x80, 0x4, 0x0, 0x0}, 142 | {"and", rm32, imm32, 0x81, 0x4, 0x0, 0x0}, 143 | {"and", rm8, imm8, 0x82, 0x4, 0x0, 0x0}, 144 | {"and", rm32, imm8, 0x83, 0x4, 0x0, 0x0}, 145 | {"bsf", r32, rm32, 0xbc, 0x0, 0x0, 0x0f}, 146 | {"bsr", r32, rm32, 0xbd, 0x0, 0x0, 0x0f}, 147 | {"bswap", r32, none, 0xc8, 0xDEAD, 0x0, 0x0f}, 148 | {"bt", rm32, imm8, 0xba, 0x4, 0x0, 0x0f}, 149 | {"btc", rm32, imm8, 0xba, 0x7, 0x0, 0x0f}, 150 | {"btr", rm32, imm8, 0xba, 0x6, 0x0, 0x0f}, 151 | {"bts", rm32, imm8, 0xba, 0x5, 0x0, 0x0f}, 152 | {"call", rel32, none, 0xe8, 0x0, 0x0, 0x0}, 153 | {"call", rm32, none, 0xff, 0x2, 0x0, 0x0}, 154 | {"cdq", edx, eax, 0x99, 0x0, 0x0, 0x0}, 155 | {"clc", none, none, 0xf8, 0x0, 0x0, 0x0}, 156 | {"cld", none, none, 0xfc, 0x0, 0x0, 0x0}, 157 | {"cli", none, none, 0xfa, 0x0, 0x0, 0x0}, 158 | {"cmc", none, none, 0xf5, 0x0, 0x0, 0x0}, 159 | {"cmovb", r32, rm32, 0x42, 0x0, 0x0, 0x0f}, 160 | {"cmovnae", r32, rm32, 0x42, 0x0, 0x0, 0x0f}, 161 | {"cmovc", r32, rm32, 0x42, 0x0, 0x0, 0x0f}, 162 | {"cmovbe", r32, rm32, 0x46, 0x0, 0x0, 0x0f}, 163 | {"cmovna", r32, rm32, 0x46, 0x0, 0x0, 0x0f}, 164 | {"cmovl", r32, rm32, 0x4c, 0x0, 0x0, 0x0f}, 165 | {"cmovnge", r32, rm32, 0x4c, 0x0, 0x0, 0x0f}, 166 | {"cmovle", r32, rm32, 0x4e, 0x0, 0x0, 0x0f}, 167 | {"cmovng", r32, rm32, 0x4e, 0x0, 0x0, 0x0f}, 168 | {"cmovnb", r32, rm32, 0x43, 0x0, 0x0, 0x0f}, 169 | {"cmovae", r32, rm32, 0x43, 0x0, 0x0, 0x0f}, 170 | {"cmovnc", r32, rm32, 0x43, 0x0, 0x0, 0x0f}, 171 | {"cmovnbe", r32, rm32, 0x47, 0x0, 0x0, 0x0f}, 172 | {"cmova", r32, rm32, 0x47, 0x0, 0x0, 0x0f}, 173 | {"cmovnl", r32, rm32, 0x4d, 0x0, 0x0, 0x0f}, 174 | {"cmovge", r32, rm32, 0x4d, 0x0, 0x0, 0x0f}, 175 | {"cmovnle", r32, rm32, 0x4f, 0x0, 0x0, 0x0f}, 176 | {"cmovg", r32, rm32, 0x4f, 0x0, 0x0, 0x0f}, 177 | {"cmovno", r32, rm32, 0x41, 0x0, 0x0, 0x0f}, 178 | {"cmovnp", r32, rm32, 0x4b, 0x0, 0x0, 0x0f}, 179 | {"cmovpo", r32, rm32, 0x4b, 0x0, 0x0, 0x0f}, 180 | {"cmovns", r32, rm32, 0x49, 0x0, 0x0, 0x0f}, 181 | {"cmovnz", r32, rm32, 0x45, 0x0, 0x0, 0x0f}, 182 | {"cmovne", r32, rm32, 0x45, 0x0, 0x0, 0x0f}, 183 | {"cmovo", r32, rm32, 0x40, 0x0, 0x0, 0x0f}, 184 | {"cmovp", r32, rm32, 0x4a, 0x0, 0x0, 0x0f}, 185 | {"cmovpe", r32, rm32, 0x4a, 0x0, 0x0, 0x0f}, 186 | {"cmovs", r32, rm32, 0x48, 0x0, 0x0, 0x0f}, 187 | {"cmovz", r32, rm32, 0x44, 0x0, 0x0, 0x0f}, 188 | {"cmove", r32, rm32, 0x44, 0x0, 0x0, 0x0f}, 189 | {"cmp", r8, rm8, 0x3a, 0x0, 0x0, 0x0}, 190 | {"cmp", r32, rm32, 0x3b, 0x0, 0x0, 0x0}, 191 | {"cmp", eax, imm32, 0x3d, 0x0, 0x0, 0x0}, 192 | {"cmp", rm8, imm8, 0x80, 0x7, 0x0, 0x0}, 193 | {"cmp", rm32, imm32, 0x81, 0x7, 0x0, 0x0}, 194 | {"cmp", rm8, imm8, 0x82, 0x7, 0x0, 0x0}, 195 | {"cmp", rm32, imm8, 0x83, 0x7, 0x0, 0x0}, 196 | {"cmpsb", rm32, imm8, 0x83, 0x7, 0x0, 0x0}, 197 | {"cmpsw", rm32, imm8, 0x83, 0x7, 0x0, 0x0}, 198 | {"cmpsd", rm32, imm8, 0x83, 0x7, 0x0, 0x0}, 199 | {"cmpxchg", rm32, eax, 0xb1, 0x0, 0x0, 0x0f}, 200 | {"crc32", r32, rm8, 0x38, 0x0, 0xf2, 0x0f}, 201 | {"crc32", r32, rm32, 0x38, 0x0, 0xf2, 0x0f}, 202 | {"cs", r32, rm32, 0x38, 0x0, 0xf2, 0x0f}, 203 | {"dec", r32, none, 0x48, 0xDEAD, 0x0, 0x0}, 204 | {"dec", rm8, none, 0xfe, 0x0, 0x0, 0x0}, 205 | {"dec", rm32, none, 0xff, 0x0, 0x0, 0x0}, 206 | {"div", rm8, none, 0xf6, 0x6, 0x0, 0x0}, 207 | {"div", rm32, none, 0xf7, 0x6, 0x0, 0x0}, 208 | {"ds", rm32, none, 0xf7, 0x6, 0x0, 0x0}, 209 | {"emms", none, none, 0x77, 0x0, 0x0, 0x0f}, 210 | {"es", none, none, 0x77, 0x0, 0x0, 0x0f}, 211 | {"fadd", none, none, 0x77, 0x0, 0x0, 0x0f}, 212 | {"fclex", none, none, 0xdb, 0x4, 0x9b, 0x0}, 213 | {"fdecstp", none, none, 0xd9, 0x6, 0x0, 0x0}, 214 | {"fdiv", none, none, 0xd9, 0x6, 0x0, 0x0}, 215 | {"fdivr", none, none, 0xd9, 0x6, 0x0, 0x0}, 216 | {"fincstp", none, none, 0xd9, 0x6, 0x0, 0x0}, 217 | {"finit", none, none, 0xdb, 0x4, 0x9b, 0x0}, 218 | {"fmul", none, none, 0xdb, 0x4, 0x9b, 0x0}, 219 | {"fnclex", none, none, 0xdb, 0x4, 0x0, 0x0}, 220 | {"fndisi", none, none, 0xdb, 0x4, 0x0, 0x0}, 221 | {"fneni", none, none, 0xdb, 0x4, 0x0, 0x0}, 222 | {"fninit", none, none, 0xdb, 0x4, 0x0, 0x0}, 223 | {"fnop", none, none, 0xd9, 0x2, 0x0, 0x0}, 224 | {"fnsetpm", none, none, 0xdb, 0x4, 0x0, 0x0}, 225 | {"fs", none, none, 0xdb, 0x4, 0x0, 0x0}, 226 | {"fsub", none, none, 0xdb, 0x4, 0x0, 0x0}, 227 | {"fsubr", none, none, 0xdb, 0x4, 0x0, 0x0}, 228 | {"fwait", none, none, 0x9b, 0x0, 0x0, 0x0}, 229 | {"wait", none, none, 0x9b, 0x0, 0x0, 0x0}, 230 | {"getsec", eax, none, 0x37, 0x0, 0x0, 0x0f}, 231 | {"gs", eax, none, 0x37, 0x0, 0x0, 0x0f}, 232 | {"hint_nop", rm32, none, 0x18, 0x4, 0x0, 0x0f}, 233 | {"hint_nop", rm32, none, 0x18, 0x5, 0x0, 0x0f}, 234 | {"hint_nop", rm32, none, 0x18, 0x6, 0x0, 0x0f}, 235 | {"hint_nop", rm32, none, 0x18, 0x7, 0x0, 0x0f}, 236 | {"hint_nop", rm32, none, 0x19, 0x0, 0x0, 0x0f}, 237 | {"hint_nop", rm32, none, 0x1a, 0x0, 0x0, 0x0f}, 238 | {"hint_nop", rm32, none, 0x1b, 0x0, 0x0, 0x0f}, 239 | {"hint_nop", rm32, none, 0x1c, 0x0, 0x0, 0x0f}, 240 | {"hint_nop", rm32, none, 0x1d, 0x0, 0x0, 0x0f}, 241 | {"hint_nop", rm32, none, 0x1e, 0x0, 0x0, 0x0f}, 242 | {"hint_nop", rm32, none, 0x1f, 0x0, 0x0, 0x0f}, 243 | {"hint_nop", rm32, none, 0x1f, 0x2, 0x0, 0x0f}, 244 | {"hint_nop", rm32, none, 0x1f, 0x3, 0x0, 0x0f}, 245 | {"hint_nop", rm32, none, 0x1f, 0x4, 0x0, 0x0f}, 246 | {"hint_nop", rm32, none, 0x1f, 0x5, 0x0, 0x0f}, 247 | {"hint_nop", rm32, none, 0x1f, 0x6, 0x0, 0x0f}, 248 | {"hint_nop", rm32, none, 0x1f, 0x7, 0x0, 0x0f}, 249 | {"hlt", none, none, 0xf4, 0x0, 0x0, 0x0}, 250 | {"idiv", edx, eax, 0xf7, 0x7, 0x0, 0x0}, 251 | {"imul", r32, rm32, 0x69, 0x0, 0x0, 0x0}, 252 | {"imul", r32, rm32, 0x6b, 0x0, 0x0, 0x0}, 253 | {"imul", edx, eax, 0xf7, 0x5, 0x0, 0x0}, 254 | {"imul", r32, rm32, 0xaf, 0x0, 0x0, 0x0f}, 255 | {"in", eax, imm8, 0xe5, 0x0, 0x0, 0x0}, 256 | {"inc", r32, none, 0x40, 0xDEAD, 0x0, 0x0}, 257 | {"inc", rm8, none, 0xfe, 0x0, 0x0, 0x0}, 258 | {"inc", rm32, none, 0xff, 0x0, 0x0, 0x0}, 259 | {"insb", rm32, none, 0xff, 0x0, 0x0, 0x0}, 260 | {"insw", rm32, none, 0xff, 0x0, 0x0, 0x0}, 261 | {"insd", rm32, none, 0xff, 0x0, 0x0, 0x0}, 262 | {"insertps", rm32, none, 0xff, 0x0, 0x0, 0x0}, 263 | {"int", imm8, none, 0xcd, 0x0, 0x0, 0x0}, 264 | {"int1", none, none, 0xf1, 0x0, 0x0, 0x0}, 265 | {"icebp", none, none, 0xf1, 0x0, 0x0, 0x0}, 266 | {"into", none, none, 0xce, 0x0, 0x0, 0x0}, 267 | {"invd", none, none, 0x8, 0x0, 0x0, 0x0f}, 268 | {"invlpg", none, none, 0x8, 0x0, 0x0, 0x0f}, 269 | {"iret", none, none, 0xcf, 0x0, 0x0, 0x0}, 270 | {"iretd", none, none, 0xcf, 0x0, 0x0, 0x0}, 271 | {"jb", rel8, none, 0x72, 0x0, 0x0, 0x0}, 272 | {"jnae", rel8, none, 0x72, 0x0, 0x0, 0x0}, 273 | {"jc", rel8, none, 0x72, 0x0, 0x0, 0x0}, 274 | {"jb", rel32, none, 0x82, 0x0, 0x0, 0x0f}, 275 | {"jnae", rel32, none, 0x82, 0x0, 0x0, 0x0f}, 276 | {"jc", rel32, none, 0x82, 0x0, 0x0, 0x0f}, 277 | {"jbe", rel8, none, 0x76, 0x0, 0x0, 0x0}, 278 | {"jna", rel8, none, 0x76, 0x0, 0x0, 0x0}, 279 | {"jbe", rel32, none, 0x86, 0x0, 0x0, 0x0f}, 280 | {"jna", rel32, none, 0x86, 0x0, 0x0, 0x0f}, 281 | {"jecxz", rel32, none, 0x86, 0x0, 0x0, 0x0f}, 282 | {"jl", rel8, none, 0x7c, 0x0, 0x0, 0x0}, 283 | {"jnge", rel8, none, 0x7c, 0x0, 0x0, 0x0}, 284 | {"jl", rel32, none, 0x8c, 0x0, 0x0, 0x0f}, 285 | {"jnge", rel32, none, 0x8c, 0x0, 0x0, 0x0f}, 286 | {"jle", rel8, none, 0x7e, 0x0, 0x0, 0x0}, 287 | {"jng", rel8, none, 0x7e, 0x0, 0x0, 0x0}, 288 | {"jle", rel32, none, 0x8e, 0x0, 0x0, 0x0f}, 289 | {"jng", rel32, none, 0x8e, 0x0, 0x0, 0x0f}, 290 | {"jmp", rel32, none, 0xe9, 0x0, 0x0, 0x0}, 291 | {"jmp", rel8, none, 0xeb, 0x0, 0x0, 0x0}, 292 | {"jmp", rm32, none, 0xff, 0x4, 0x0, 0x0}, 293 | {"jnb", rel8, none, 0x73, 0x0, 0x0, 0x0}, 294 | {"jae", rel8, none, 0x73, 0x0, 0x0, 0x0}, 295 | {"jnc", rel8, none, 0x73, 0x0, 0x0, 0x0}, 296 | {"jnb", rel32, none, 0x83, 0x0, 0x0, 0x0f}, 297 | {"jae", rel32, none, 0x83, 0x0, 0x0, 0x0f}, 298 | {"jnc", rel32, none, 0x83, 0x0, 0x0, 0x0f}, 299 | {"jnbe", rel8, none, 0x77, 0x0, 0x0, 0x0}, 300 | {"ja", rel8, none, 0x77, 0x0, 0x0, 0x0}, 301 | {"jnbe", rel32, none, 0x87, 0x0, 0x0, 0x0f}, 302 | {"ja", rel32, none, 0x87, 0x0, 0x0, 0x0f}, 303 | {"jnl", rel8, none, 0x7d, 0x0, 0x0, 0x0}, 304 | {"jge", rel8, none, 0x7d, 0x0, 0x0, 0x0}, 305 | {"jnl", rel32, none, 0x8d, 0x0, 0x0, 0x0f}, 306 | {"jge", rel32, none, 0x8d, 0x0, 0x0, 0x0f}, 307 | {"jnle", rel8, none, 0x7f, 0x0, 0x0, 0x0}, 308 | {"jg", rel8, none, 0x7f, 0x0, 0x0, 0x0}, 309 | {"jnle", rel32, none, 0x8f, 0x0, 0x0, 0x0f}, 310 | {"jg", rel32, none, 0x8f, 0x0, 0x0, 0x0f}, 311 | {"jno", rel8, none, 0x71, 0x0, 0x0, 0x0}, 312 | {"jno", rel32, none, 0x81, 0x0, 0x0, 0x0f}, 313 | {"jnp", rel8, none, 0x7b, 0x0, 0x0, 0x0}, 314 | {"jpo", rel8, none, 0x7b, 0x0, 0x0, 0x0}, 315 | {"jnp", rel32, none, 0x8b, 0x0, 0x0, 0x0f}, 316 | {"jpo", rel32, none, 0x8b, 0x0, 0x0, 0x0f}, 317 | {"jns", rel8, none, 0x79, 0x0, 0x0, 0x0}, 318 | {"jns", rel32, none, 0x89, 0x0, 0x0, 0x0f}, 319 | {"jnz", rel8, none, 0x75, 0x0, 0x0, 0x0}, 320 | {"jne", rel8, none, 0x75, 0x0, 0x0, 0x0}, 321 | {"jnz", rel32, none, 0x85, 0x0, 0x0, 0x0f}, 322 | {"jne", rel32, none, 0x85, 0x0, 0x0, 0x0f}, 323 | {"jo", rel8, none, 0x70, 0x0, 0x0, 0x0}, 324 | {"jo", rel32, none, 0x80, 0x0, 0x0, 0x0f}, 325 | {"jp", rel8, none, 0x7a, 0x0, 0x0, 0x0}, 326 | {"jpe", rel8, none, 0x7a, 0x0, 0x0, 0x0}, 327 | {"jp", rel32, none, 0x8a, 0x0, 0x0, 0x0f}, 328 | {"jpe", rel32, none, 0x8a, 0x0, 0x0, 0x0f}, 329 | {"js", rel8, none, 0x78, 0x0, 0x0, 0x0}, 330 | {"js", rel32, none, 0x88, 0x0, 0x0, 0x0f}, 331 | {"jz", rel8, none, 0x74, 0x0, 0x0, 0x0}, 332 | {"je", rel8, none, 0x74, 0x0, 0x0, 0x0}, 333 | {"jz", rel32, none, 0x84, 0x0, 0x0, 0x0f}, 334 | {"je", rel32, none, 0x84, 0x0, 0x0, 0x0f}, 335 | {"lar", rel32, none, 0x84, 0x0, 0x0, 0x0f}, 336 | {"lds", ds, r32, 0xc5, 0x0, 0x0, 0x0}, 337 | {"lea", r32, rel32, 0x8d, 0x0, 0x0, 0x0}, 338 | {"les", es, r32, 0xc4, 0x0, 0x0, 0x0}, 339 | {"lfence", none, none, 0xae, 0x5, 0x0, 0x0f}, 340 | {"lfs", fs, r32, 0xb4, 0x0, 0x0, 0x0f}, 341 | {"lgdt", r32, none, 0x1, 0x0, 0x0, 0x0f}, 342 | {"lgs", gs, r32, 0xb5, 0x0, 0x0, 0x0f}, 343 | {"lidt", rel32, none, 0x1, 0x0, 0x0, 0x0f}, 344 | {"lmsw", gs, r32, 0xb5, 0x0, 0x0, 0x0f}, 345 | {"lock", gs, r32, 0xb5, 0x0, 0x0, 0x0f}, 346 | {"lodsb", gs, r32, 0xb5, 0x0, 0x0, 0x0f}, 347 | {"lodsw", gs, r32, 0xb5, 0x0, 0x0, 0x0f}, 348 | {"lodsd", gs, r32, 0xb5, 0x0, 0x0, 0x0f}, 349 | {"loop", ecx, rel8, 0xe2, 0x0, 0x0, 0x0}, 350 | {"loopnz", ecx, rel8, 0xe0, 0x0, 0x0, 0x0}, 351 | {"loopne", ecx, rel8, 0xe0, 0x0, 0x0, 0x0}, 352 | {"loopz", ecx, rel8, 0xe1, 0x0, 0x0, 0x0}, 353 | {"loope", ecx, rel8, 0xe1, 0x0, 0x0, 0x0}, 354 | {"lsl", ecx, rel8, 0xe1, 0x0, 0x0, 0x0}, 355 | {"lss", ss, r32, 0xb2, 0x0, 0x0, 0x0f}, 356 | {"mfence", none, none, 0xae, 0x6, 0x0, 0x0f}, 357 | {"monitor", none, none, 0xae, 0x6, 0x0, 0x0f}, 358 | {"mov", r8, rm8, 0x8a, 0x0, 0x0, 0x0}, 359 | {"mov", r32, rm32, 0x8b, 0x0, 0x0, 0x0}, 360 | {"mov", r32, rm32, 0x8b, 0x0, 0x0, 0x0}, 361 | {"mov", sreg, rm32, 0x8e, 0x0, 0x0, 0x0}, 362 | {"mov", r8, imm8, 0xb0, 0xDEAD, 0x0, 0x0}, 363 | {"mov", r32, imm32, 0xb8, 0xDEAD, 0x0, 0x0}, 364 | {"mov", rm8, imm8, 0xc6, 0x0, 0x0, 0x0}, 365 | {"mov", rm32, imm32, 0xc7, 0x0, 0x0, 0x0}, 366 | {"mov", r32, crn, 0x20, 0x0, 0x0, 0x0f}, 367 | {"mov", r32, crn, 0x20, 0x0, 0x0, 0x0f}, 368 | {"mov", crn, r32, 0x22, 0x0, 0x0, 0x0f}, 369 | {"mov", crn, r32, 0x22, 0x0, 0x0, 0x0f}, 370 | {"movsb", crn, r32, 0x22, 0x0, 0x0, 0x0f}, 371 | {"movsw", crn, r32, 0x22, 0x0, 0x0, 0x0f}, 372 | {"movsd", crn, r32, 0x22, 0x0, 0x0, 0x0f}, 373 | {"movsx", r32, rm8, 0xbe, 0x0, 0x0, 0x0f}, 374 | {"movsx", r32, rm32, 0xbf, 0x0, 0x0, 0x0f}, 375 | {"movzx", r32, rm8, 0xb6, 0x0, 0x0, 0x0f}, 376 | {"movzx", r32, rm32, 0xb7, 0x0, 0x0, 0x0f}, 377 | {"mul", rm8, none, 0xf6, 0x4, 0x0, 0x0}, 378 | {"mul", rm32, none, 0xf7, 0x4, 0x0, 0x0}, 379 | {"mwait", rm32, none, 0xf7, 0x4, 0x0, 0x0}, 380 | {"neg", rm8, none, 0xf6, 0x3, 0x0, 0x0}, 381 | {"neg", rm32, none, 0xf7, 0x3, 0x0, 0x0}, 382 | {"nop", none, none, 0x90, 0x0, 0x0, 0x0}, 383 | {"nop", rm32, none, 0x0d, 0x0, 0x0, 0x0f}, 384 | {"nop", rm32, none, 0x1f, 0x0, 0x0, 0x0f}, 385 | {"not", rm8, none, 0xf6, 0x2, 0x0, 0x0}, 386 | {"not", rm32, none, 0xf7, 0x2, 0x0, 0x0}, 387 | {"or", r8, rm8, 0x0a, 0x0, 0x0, 0x0}, 388 | {"or", r32, rm32, 0x0b, 0x0, 0x0, 0x0}, 389 | {"or", eax, imm32, 0x0d, 0x0, 0x0, 0x0}, 390 | {"or", rm8, imm8, 0x80, 0x0, 0x0, 0x0}, 391 | {"or", rm32, imm32, 0x81, 0x0, 0x0, 0x0}, 392 | {"or", rm8, imm8, 0x82, 0x0, 0x0, 0x0}, 393 | {"or", rm32, imm8, 0x83, 0x0, 0x0, 0x0}, 394 | {"out", imm8, eax, 0xe7, 0x0, 0x0, 0x0}, 395 | {"outsb", imm8, eax, 0xe7, 0x0, 0x0, 0x0}, 396 | {"outsw", imm8, eax, 0xe7, 0x0, 0x0, 0x0}, 397 | {"outsd", imm8, eax, 0xe7, 0x0, 0x0, 0x0}, 398 | {"pause", none, none, 0x90, 0x0, 0xf3, 0x0}, 399 | {"pextrb", none, none, 0x90, 0x0, 0xf3, 0x0}, 400 | {"pextrq", none, none, 0x90, 0x0, 0xf3, 0x0}, 401 | {"pextrw", none, none, 0x90, 0x0, 0xf3, 0x0}, 402 | {"pinsrb", none, none, 0x90, 0x0, 0xf3, 0x0}, 403 | {"pinsrq", none, none, 0x90, 0x0, 0xf3, 0x0}, 404 | {"pinsrw", none, none, 0x90, 0x0, 0xf3, 0x0}, 405 | {"pinsrw", none, none, 0x90, 0x0, 0xf3, 0x0}, 406 | {"pmovsxbd", none, none, 0x90, 0x0, 0xf3, 0x0}, 407 | {"pmovsxbq", none, none, 0x90, 0x0, 0xf3, 0x0}, 408 | {"pmovsxbw", none, none, 0x90, 0x0, 0xf3, 0x0}, 409 | {"pmovsxdq", none, none, 0x90, 0x0, 0xf3, 0x0}, 410 | {"pmovsxwd", none, none, 0x90, 0x0, 0xf3, 0x0}, 411 | {"pmovsxwq", none, none, 0x90, 0x0, 0xf3, 0x0}, 412 | {"pmovzxbd", none, none, 0x90, 0x0, 0xf3, 0x0}, 413 | {"pmovzxbq", none, none, 0x90, 0x0, 0xf3, 0x0}, 414 | {"pmovzxbw", none, none, 0x90, 0x0, 0xf3, 0x0}, 415 | {"pmovzxdq", none, none, 0x90, 0x0, 0xf3, 0x0}, 416 | {"pmovzxwd", none, none, 0x90, 0x0, 0xf3, 0x0}, 417 | {"pmovzxwq", none, none, 0x90, 0x0, 0xf3, 0x0}, 418 | {"pop", es, none, 0x7, 0x0, 0x0, 0x0}, 419 | {"pop", ss, none, 0x17, 0x0, 0x0, 0x0}, 420 | {"pop", ds, none, 0x1f, 0x0, 0x0, 0x0}, 421 | {"pop", r32, none, 0x58, 0xDEAD, 0x0, 0x0}, 422 | {"pop", rm32, none, 0x8f, 0x0, 0x0, 0x0}, 423 | {"pop", fs, none, 0xa1, 0x0, 0x0, 0x0f}, 424 | {"pop", gs, none, 0xa9, 0x0, 0x0, 0x0f}, 425 | {"popa", none, none, 0x61, 0x0, 0x0, 0x0}, 426 | {"popad", none, none, 0x61, 0x0, 0x0, 0x0}, 427 | {"popcnt", r32, rm32, 0xb8, 0x0, 0xf3, 0x0f}, 428 | {"popf", none, none, 0x9d, 0x0, 0x0, 0x0}, 429 | {"popfd", none, none, 0x9d, 0x0, 0x0, 0x0}, 430 | {"push", es, none, 0x6, 0x0, 0x0, 0x0}, 431 | {"push", cs, none, 0x0e, 0x0, 0x0, 0x0}, 432 | {"push", ss, none, 0x32, 0x0, 0x0, 0x0}, 433 | {"push", ds, none, 0x1e, 0x0, 0x0, 0x0}, 434 | {"push", r32, none, 0x50, 0xDEAD, 0x0, 0x0}, 435 | {"push", imm32, none, 0x68, 0x0, 0x0, 0x0}, 436 | {"push", imm8, none, 0x6a, 0x0, 0x0, 0x0}, 437 | {"push", rm32, none, 0xff, 0x6, 0x0, 0x0}, 438 | {"push", fs, none, 0xa0, 0x0, 0x0, 0x0f}, 439 | {"push", gs, none, 0xa8, 0x0, 0x0, 0x0f}, 440 | {"pusha", none, none, 0x60, 0x0, 0x0, 0x0}, 441 | {"pushad", none, none, 0x60, 0x0, 0x0, 0x0}, 442 | {"pushf", none, none, 0x9c, 0x0, 0x0, 0x0}, 443 | {"pushfd", none, none, 0x9c, 0x0, 0x0, 0x0}, 444 | {"rcl", rm8, imm8, 0xc0, 0x2, 0x0, 0x0}, 445 | {"rcl", rm32, imm8, 0xc1, 0x2, 0x0, 0x0}, 446 | {"rcl", rm8, none, 0xd0, 0x2, 0x0, 0x0}, 447 | {"rcl", rm32, none, 0xd1, 0x2, 0x0, 0x0}, 448 | {"rcr", rm8, imm8, 0xc0, 0x3, 0x0, 0x0}, 449 | {"rcr", rm32, imm8, 0xc1, 0x3, 0x0, 0x0}, 450 | {"rcr", rm8, none, 0xd0, 0x3, 0x0, 0x0}, 451 | {"rcr", rm32, none, 0xd1, 0x3, 0x0, 0x0}, 452 | {"rdmsr", eax, edx, 0x32, 0x0, 0x0, 0x0f}, 453 | {"rdpmc", eax, edx, 0x33, 0x0, 0x0, 0x0f}, 454 | {"rdtsc", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 455 | {"rdtscp", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 456 | {"rep", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 457 | {"rep", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 458 | {"repnz", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 459 | {"repne", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 460 | {"repz", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 461 | {"repe", eax, edx, 0x31, 0x0, 0x0, 0x0f}, 462 | {"retf", imm32, none, 0xca, 0x0, 0x0, 0x0}, 463 | {"retf", none, none, 0xcb, 0x0, 0x0, 0x0}, 464 | {"retn", imm32, none, 0xc2, 0x0, 0x0, 0x0}, 465 | {"retn", none, none, 0xc3, 0x0, 0x0, 0x0}, 466 | {"rol", rm8, imm8, 0xc0, 0x0, 0x0, 0x0}, 467 | {"rol", rm32, imm8, 0xc1, 0x0, 0x0, 0x0}, 468 | {"rol", rm8, none, 0xd0, 0x0, 0x0, 0x0}, 469 | {"rol", rm32, none, 0xd1, 0x0, 0x0, 0x0}, 470 | {"ror", rm8, imm8, 0xc0, 0x0, 0x0, 0x0}, 471 | {"ror", rm32, imm8, 0xc1, 0x0, 0x0, 0x0}, 472 | {"ror", rm8, none, 0xd0, 0x0, 0x0, 0x0}, 473 | {"ror", rm32, none, 0xd1, 0x0, 0x0, 0x0}, 474 | {"rsm", none, none, 0xaa, 0x0, 0x0, 0x0f}, 475 | {"sal", rm8, imm8, 0xc0, 0x6, 0x0, 0x0}, 476 | {"shl", rm8, imm8, 0xc0, 0x6, 0x0, 0x0}, 477 | {"sal", rm32, imm8, 0xc1, 0x6, 0x0, 0x0}, 478 | {"shl", rm32, imm8, 0xc1, 0x6, 0x0, 0x0}, 479 | {"sal", rm8, none, 0xd0, 0x6, 0x0, 0x0}, 480 | {"shl", rm8, none, 0xd0, 0x6, 0x0, 0x0}, 481 | {"sal", rm32, none, 0xd1, 0x6, 0x0, 0x0}, 482 | {"shl", rm32, none, 0xd1, 0x6, 0x0, 0x0}, 483 | {"shl", rm32, none, 0xd1, 0x6, 0x0, 0x0}, 484 | {"shl", rm32, none, 0xd1, 0x6, 0x0, 0x0}, 485 | {"setalc", rm32, none, 0xd1, 0x6, 0x0, 0x0}, 486 | {"sar", rm8, imm8, 0xc0, 0x7, 0x0, 0x0}, 487 | {"sar", rm32, imm8, 0xc1, 0x7, 0x0, 0x0}, 488 | {"sar", rm8, none, 0xd0, 0x7, 0x0, 0x0}, 489 | {"sar", rm32, none, 0xd1, 0x7, 0x0, 0x0}, 490 | {"sbb", r8, rm8, 0x1a, 0x0, 0x0, 0x0}, 491 | {"sbb", r32, rm32, 0x1b, 0x0, 0x0, 0x0}, 492 | {"sbb", eax, imm32, 0x1d, 0x0, 0x0, 0x0}, 493 | {"sbb", rm8, imm8, 0x80, 0x3, 0x0, 0x0}, 494 | {"sbb", rm32, imm32, 0x81, 0x3, 0x0, 0x0}, 495 | {"sbb", rm8, imm8, 0x82, 0x3, 0x0, 0x0}, 496 | {"sbb", rm32, imm8, 0x83, 0x3, 0x0, 0x0}, 497 | {"scasb", rm32, imm8, 0x83, 0x3, 0x0, 0x0}, 498 | {"scasw", rm32, imm8, 0x83, 0x3, 0x0, 0x0}, 499 | {"scasd", rm32, imm8, 0x83, 0x3, 0x0, 0x0}, 500 | {"setb", rm8, none, 0x92, 0x0, 0x0, 0x0f}, 501 | {"setnae", rm8, none, 0x92, 0x0, 0x0, 0x0f}, 502 | {"setc", rm8, none, 0x92, 0x0, 0x0, 0x0f}, 503 | {"setbe", rm8, none, 0x96, 0x0, 0x0, 0x0f}, 504 | {"setna", rm8, none, 0x96, 0x0, 0x0, 0x0f}, 505 | {"setl", rm8, none, 0x9c, 0x0, 0x0, 0x0f}, 506 | {"setnge", rm8, none, 0x9c, 0x0, 0x0, 0x0f}, 507 | {"setle", rm8, none, 0x9e, 0x0, 0x0, 0x0f}, 508 | {"setng", rm8, none, 0x9e, 0x0, 0x0, 0x0f}, 509 | {"setnb", rm8, none, 0x93, 0x0, 0x0, 0x0f}, 510 | {"setae", rm8, none, 0x93, 0x0, 0x0, 0x0f}, 511 | {"setnc", rm8, none, 0x93, 0x0, 0x0, 0x0f}, 512 | {"setnbe", rm8, none, 0x97, 0x0, 0x0, 0x0f}, 513 | {"seta", rm8, none, 0x97, 0x0, 0x0, 0x0f}, 514 | {"setnl", rm8, none, 0x9d, 0x0, 0x0, 0x0f}, 515 | {"setge", rm8, none, 0x9d, 0x0, 0x0, 0x0f}, 516 | {"setnle", rm8, none, 0x9f, 0x0, 0x0, 0x0f}, 517 | {"setg", rm8, none, 0x9f, 0x0, 0x0, 0x0f}, 518 | {"setno", rm8, none, 0x91, 0x0, 0x0, 0x0f}, 519 | {"setnp", rm8, none, 0x9b, 0x0, 0x0, 0x0f}, 520 | {"setpo", rm8, none, 0x9b, 0x0, 0x0, 0x0f}, 521 | {"setns", rm8, none, 0x99, 0x0, 0x0, 0x0f}, 522 | {"setnz", rm8, none, 0x95, 0x0, 0x0, 0x0f}, 523 | {"setne", rm8, none, 0x95, 0x0, 0x0, 0x0f}, 524 | {"seto", rm8, none, 0x90, 0x0, 0x0, 0x0f}, 525 | {"setp", rm8, none, 0x9a, 0x0, 0x0, 0x0f}, 526 | {"setpe", rm8, none, 0x9a, 0x0, 0x0, 0x0f}, 527 | {"sets", rm8, none, 0x98, 0x0, 0x0, 0x0f}, 528 | {"setz", rm8, none, 0x94, 0x0, 0x0, 0x0f}, 529 | {"sete", rm8, none, 0x94, 0x0, 0x0, 0x0f}, 530 | {"sfence", none, none, 0xae, 0x7, 0x0, 0x0f}, 531 | {"sgdt", none, none, 0xae, 0x7, 0x0, 0x0f}, 532 | {"shl", rm8, imm8, 0xc0, 0x4, 0x0, 0x0}, 533 | {"sal", rm8, imm8, 0xc0, 0x4, 0x0, 0x0}, 534 | {"shl", rm32, imm8, 0xc1, 0x4, 0x0, 0x0}, 535 | {"sal", rm32, imm8, 0xc1, 0x4, 0x0, 0x0}, 536 | {"shl", rm8, none, 0xd0, 0x4, 0x0, 0x0}, 537 | {"sal", rm8, none, 0xd0, 0x4, 0x0, 0x0}, 538 | {"shl", rm32, none, 0xd1, 0x4, 0x0, 0x0}, 539 | {"sal", rm32, none, 0xd1, 0x4, 0x0, 0x0}, 540 | {"sal", rm32, none, 0xd1, 0x4, 0x0, 0x0}, 541 | {"sal", rm32, none, 0xd1, 0x4, 0x0, 0x0}, 542 | {"shr", rm8, imm8, 0xc0, 0x5, 0x0, 0x0}, 543 | {"shr", rm32, imm8, 0xc1, 0x5, 0x0, 0x0}, 544 | {"shr", rm8, none, 0xd0, 0x5, 0x0, 0x0}, 545 | {"shr", rm32, none, 0xd1, 0x5, 0x0, 0x0}, 546 | {"sidt", rm32, none, 0xd1, 0x5, 0x0, 0x0}, 547 | {"sldt", rm32, none, 0xd1, 0x5, 0x0, 0x0}, 548 | {"smsw", rm32, none, 0xd1, 0x5, 0x0, 0x0}, 549 | {"smsw", rm32, none, 0xd1, 0x5, 0x0, 0x0}, 550 | {"ss", rm32, none, 0xd1, 0x5, 0x0, 0x0}, 551 | {"stc", none, none, 0xf9, 0x0, 0x0, 0x0}, 552 | {"std", none, none, 0xfd, 0x0, 0x0, 0x0}, 553 | {"sti", none, none, 0xfb, 0x0, 0x0, 0x0}, 554 | {"stos", none, none, 0xaa, 0x0, 0x0, 0x0}, 555 | {"stosb", none, none, 0xaa, 0x0, 0x0, 0x0}, 556 | {"stos", none, none, 0xab, 0x0, 0x0, 0x0}, 557 | {"stosw", none, none, 0xab, 0x0, 0x0, 0x0}, 558 | {"stos", none, none, 0xab, 0x0, 0x0, 0x0}, 559 | {"stosd", none, none, 0xab, 0x0, 0x0, 0x0}, 560 | {"str", none, none, 0xab, 0x0, 0x0, 0x0}, 561 | {"sub", r8, rm8, 0x2a, 0x0, 0x0, 0x0}, 562 | {"sub", r32, rm32, 0x2b, 0x0, 0x0, 0x0}, 563 | {"sub", eax, imm32, 0x2d, 0x0, 0x0, 0x0}, 564 | {"sub", rm8, imm8, 0x80, 0x5, 0x0, 0x0}, 565 | {"sub", rm32, imm32, 0x81, 0x5, 0x0, 0x0}, 566 | {"sub", rm8, imm8, 0x82, 0x5, 0x0, 0x0}, 567 | {"sub", rm32, imm8, 0x83, 0x5, 0x0, 0x0}, 568 | {"sysenter", none, none, 0x34, 0x0, 0x0, 0x0f}, 569 | {"sysexit", none, none, 0x35, 0x0, 0x0, 0x0f}, 570 | {"test", rm8, r8, 0x84, 0x0, 0x0, 0x0}, 571 | {"test", rm32, r32, 0x85, 0x0, 0x0, 0x0}, 572 | {"test", eax, imm32, 0xa9, 0x0, 0x0, 0x0}, 573 | {"test", rm8, imm8, 0xf6, 0x0, 0x0, 0x0}, 574 | {"test", rm8, imm8, 0xf6, 0x0, 0x0, 0x0}, 575 | {"test", rm32, imm32, 0xf7, 0x0, 0x0, 0x0}, 576 | {"test", rm32, imm32, 0xf7, 0x0, 0x0, 0x0}, 577 | {"ud2", none, none, 0x0b, 0x0, 0x0, 0x0f}, 578 | {"verr", rm32, none, 0x0, 0x4, 0x0, 0x0f}, 579 | {"verw", rm32, none, 0x0, 0x5, 0x0, 0x0f}, 580 | {"vmcall", rm32, none, 0x0, 0x5, 0x0, 0x0f}, 581 | {"vmlaunch", rm32, none, 0x0, 0x5, 0x0, 0x0f}, 582 | {"vmresume", rm32, none, 0x0, 0x5, 0x0, 0x0f}, 583 | {"vmwrite", r32, rm32, 0x79, 0x0, 0x0, 0x0f}, 584 | {"vmxoff", r32, rm32, 0x79, 0x0, 0x0, 0x0f}, 585 | {"wbinvd", none, none, 0x9, 0x0, 0x0, 0x0f}, 586 | {"xchg", r8, rm8, 0x86, 0x0, 0x0, 0x0}, 587 | {"xchg", r32, rm32, 0x87, 0x0, 0x0, 0x0}, 588 | {"xchg", r32, eax, 0x90, 0xDEAD, 0x0, 0x0}, 589 | {"xgetbv", r32, eax, 0x90, 0xDEAD, 0x0, 0x0}, 590 | {"xlatb", r32, eax, 0x90, 0xDEAD, 0x0, 0x0}, 591 | {"xor", r8, rm8, 0x32, 0x0, 0x0, 0x0}, 592 | {"xor", r32, rm32, 0x33, 0x0, 0x0, 0x0}, 593 | {"xor", eax, imm32, 0x35, 0x0, 0x0, 0x0}, 594 | {"xor", rm8, imm8, 0x80, 0x6, 0x0, 0x0}, 595 | {"xor", rm32, imm32, 0x81, 0x6, 0x0, 0x0}, 596 | {"xor", rm8, imm8, 0x82, 0x6, 0x0, 0x0}, 597 | {"xor", rm32, imm8, 0x83, 0x6, 0x0, 0x0}, 598 | // {"xsave", m, edx, 0xae, 0x4, 0x0, 0x0f}, 599 | // {"xsetbv", m, edx, 0xae, 0x4, 0x0, 0x0f}, 600 | }; 601 | #endif 602 | --------------------------------------------------------------------------------