├── LICENSE.txt ├── Makefile ├── README.md ├── bin └── .gitkeep ├── include ├── types.h ├── x86_dasm.h ├── x86_dasm_macros.h └── x86_dasm_tables.h ├── obj └── .gitkeep ├── src ├── main.c ├── x86_dasm.c └── x86_dasm_tables.c └── test ├── test-x32.bin └── test-x64.bin /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This file is part of x86_dasm. 3 | # 4 | # x86_dasm is a compact x86-64 disassembling library 5 | # 6 | # Copyright 2014 / the`janitor / < email: base64dec(dGhlLmphbml0b3JAcHJvdG9ubWFpbC5jb20=) > 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | # To avoid "missing separator" errors when TABs get converted to spaces 22 | ifeq ($(origin .RECIPEPREFIX), undefined) 23 | $(error Variable .RECIPEPREFIX is unsupported, upgrade to GNU Make 4.0 or later) 24 | endif 25 | .RECIPEPREFIX = > 26 | 27 | # Programs 28 | CC = gcc 29 | AS = nasm 30 | CFLAGS = -Wall -Iinclude/ -std=c99 -O3 # -DX86_DASM_DEBUG 31 | LFLAGS = -s 32 | AFLAGS = -f bin 33 | 34 | SRC_DIR = src 35 | BIN_DIR = bin 36 | OBJ_DIR = obj 37 | 38 | SOURCES_C = $(wildcard $(SRC_DIR)/*.c) 39 | OBJECTS_C = $(patsubst $(SRC_DIR)/%,$(OBJ_DIR)/%,$(SOURCES_C:.c=.o)) 40 | 41 | all: x86_dasm 42 | 43 | x86_dasm: $(OBJECTS_C) 44 | > $(CC) $(LFLAGS) $^ -o $(BIN_DIR)/$@ 45 | 46 | $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c 47 | > $(CC) $(CFLAGS) -c $< -o $@ 48 | 49 | clean: 50 | > rm -rf $(BIN_DIR)/* $(OBJ_DIR)/* 51 | 52 | rebuild: clean all 53 | 54 | .PHONY : clean 55 | .SILENT : clean 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # x86_dasm 2 | 3 | This lightweight library aims at providing x86-64 disassembling features while being compact and simple to understand and fix. There are no dependencies other than the C standard library, which can also be avoided with slight modifications, depending on the compilation options. It does not use any dynamic memory allocation. 4 | 5 | It is programmed entirely in C99 and supports all `x86` and `x86-64`/`AMD64` instructions and most ISA extensions (e.g. `AVX512` is currently not supported). 6 | 7 | # Build 8 | 9 | Compilation switches that can optionally be defined: 10 | 11 | - `X86_DASM_DEBUG` to enable verbose debug output 12 | - `X86_DASM_NOFMT` to disable all the instruction formatting (no strings) 13 | 14 | ``` 15 | make all 16 | ``` 17 | 18 | # Usage example 19 | 20 | ```c 21 | x86_dasm_context_t x86_dctx = {0}; 22 | 23 | uint8_t code[] = { 24 | 0xeb, 0xfe 25 | }; 26 | 27 | x86_set_buffer(&x86_dctx, code); 28 | x86_set_dmode(&x86_dctx, X86_DMODE_64BIT); 29 | x86_set_ip(&x86_dctx, 0x7ffe0000); 30 | 31 | if(x86_dasm(&x86_dctx) == 0) 32 | printf("%s", x86_dctx.inst_str); 33 | ``` 34 | 35 | # Output example 36 | 37 | ``` 38 | 0000 | 6A 60 | push 60 39 | 0002 | 5A | pop rdx 40 | 0003 | 68 63 61 6C 63 | push 636C6163 41 | 0008 | 54 | push rsp 42 | 0009 | 59 | pop rcx 43 | 000A | 48 29 D4 | sub rsp, rdx 44 | 000D | 65 48 8B 32 | mov rsi, qword ptr gs:[rdx] 45 | 0011 | 48 8B 76 18 | mov rsi, qword ptr ds:[rsi+18] 46 | 0015 | 48 8B 76 10 | mov rsi, qword ptr ds:[rsi+10] 47 | 0019 | 48 AD | lodsq rax, qword ptr ds:[rsi] 48 | 001B | 48 8B 30 | mov rsi, qword ptr ds:[rax] 49 | 001E | 48 8B 7E 30 | mov rdi, qword ptr ds:[rsi+30] 50 | 0022 | 03 57 3C | add edx, dword ptr ds:[rdi+3C] 51 | 0025 | 8B 5C 17 28 | mov ebx, dword ptr ds:[rdi+rdx+28] 52 | 0029 | 8B 74 1F 20 | mov esi, dword ptr ds:[rdi+rbx+20] 53 | 002D | 48 01 FE | add rsi, rdi 54 | 0030 | 8B 54 1F 24 | mov edx, dword ptr ds:[rdi+rbx+24] 55 | 0034 | 0F B7 2C 17 | movzx ebp, word ptr ds:[rdi+rdx] 56 | 0038 | 8D 52 02 | lea edx, ds:[rdx+2] 57 | 003B | AD | lodsd eax, dword ptr ds:[rsi] 58 | 003C | 81 3C 07 57 69 6E 45 | cmp dword ptr ds:[rdi+rax], 456E6957 59 | 0043 | 75 EF | jnz short 34 60 | 0045 | 8B 74 1F 1C | mov esi, dword ptr ds:[rdi+rbx+1C] 61 | 0049 | 48 01 FE | add rsi, rdi 62 | 004C | 8B 34 AE | mov esi, dword ptr ds:[rsi+rbp*4] 63 | 004F | 48 01 F7 | add rdi, rsi 64 | 0052 | 99 | cdq 65 | 0053 | FF D7 | call rdi 66 | ``` 67 | 68 | # Helper macros for conditional expressions 69 | 70 | ```c 71 | #include "x86_dasm_macros.h" 72 | 73 | // ... 74 | 75 | if(x86_dasm(&x86_dctx) == 0) 76 | { 77 | if(X86M(&x86_dctx, ANY, REG(), REG())) 78 | printf("Matched an instruction with two register operands"); 79 | 80 | if(X86M(&x86_dctx, MOV, REG(), MEXPR())) 81 | printf("Matched: mov reg, mem"); 82 | 83 | if(X86M(&x86_dctx, CALL, REG(EDI))) 84 | printf("Matched: call edi"); 85 | } 86 | ``` 87 | 88 | # License 89 | 90 | `x86_dasm` is licensed under the Apache License, Version 2.0 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejanit0r/x86_dasm/20dd43fb4589c5e41160ed6279cd3041f766f400/bin/.gitkeep -------------------------------------------------------------------------------- /include/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of x86_dasm. 4 | 5 | x86_dasm is a compact x86-64 disassembling library 6 | 7 | Copyright 2014 / the`janitor / < email: base64dec(dGhlLmphbml0b3JAcHJvdG9ubWFpbC5jb20=) > 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | */ 22 | #ifndef _TYPES_H_ 23 | #define _TYPES_H_ 24 | 25 | #if defined(_MSC_VER) 26 | 27 | #include 28 | 29 | typedef LARGE_INTEGER large_int_t; 30 | 31 | #if(_MSC_VER < 1300) 32 | 33 | typedef SIZE_T size_t; 34 | typedef signed char int8_t; 35 | typedef signed short int16_t; 36 | typedef signed int int32_t; 37 | typedef long long int64_t 38 | 39 | typedef unsigned char uint8_t; 40 | typedef unsigned short uint16_t; 41 | typedef unsigned int uint32_t; 42 | typedef unsigned long long uint64_t; 43 | 44 | #else 45 | 46 | typedef signed __int8 int8_t; 47 | typedef signed __int16 int16_t; 48 | typedef signed __int32 int32_t; 49 | typedef signed __int64 int64_t; 50 | 51 | typedef unsigned __int8 uint8_t; 52 | typedef unsigned __int16 uint16_t; 53 | typedef unsigned __int32 uint32_t; 54 | typedef unsigned __int64 uint64_t; 55 | 56 | typedef signed long long_t; 57 | typedef unsigned long ulong_t; 58 | typedef unsigned char uchar_t; 59 | typedef unsigned short ushort_t; 60 | 61 | #endif 62 | 63 | #if defined(_WIN64) 64 | 65 | typedef signed __int64 intptr_t; 66 | typedef unsigned __int64 uintptr_t; 67 | typedef unsigned __int64 size_t; 68 | 69 | #else 70 | 71 | typedef signed int intptr_t; 72 | typedef unsigned int uintptr_t; 73 | 74 | #endif 75 | 76 | #else 77 | 78 | #include 79 | #include 80 | 81 | typedef signed long long_t; 82 | typedef unsigned long ulong_t; 83 | typedef unsigned char uchar_t; 84 | typedef unsigned short ushort_t; 85 | 86 | #endif 87 | 88 | typedef unsigned int bool_t; 89 | 90 | #define true 1 91 | #define false 0 92 | 93 | #ifndef __cplusplus 94 | #define NULL ((void *)0) 95 | #endif 96 | 97 | #if 0 98 | #ifndef offsetof 99 | #define offsetof(s,m) (size_t)&(((s *)0)->m) 100 | #endif 101 | #endif 102 | 103 | #ifndef countof 104 | #define countof(a) (sizeof(a) / sizeof(a[0])) 105 | #endif 106 | 107 | #define roundup(a, b) \ 108 | (((ulong_t)(a) + (ulong_t)(b) - 1) & ~((ulong_t)(b) - 1)) 109 | 110 | /* token paste */ 111 | #define PASTE_INTERNAL(a, b) a##b 112 | 113 | /* level of indirection for recursive expansion */ 114 | #define PASTE_TOKEN(a, b) PASTE_INTERNAL(a, b) 115 | 116 | #endif //_TYPES_H_ 117 | -------------------------------------------------------------------------------- /include/x86_dasm.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of x86_dasm. 4 | 5 | x86_dasm is a compact x86-64 disassembling library 6 | 7 | Copyright 2014 / the`janitor / < email: base64dec(dGhlLmphbml0b3JAcHJvdG9ubWFpbC5jb20=) > 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | */ 22 | #ifndef _DASM_H_ 23 | #define _DASM_H_ 24 | 25 | #include "types.h" 26 | #include "x86_dasm_tables.h" 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* 35 | #define X86_DASM_DEBUG : enable debug output 36 | #define X86_DASM_NOFMT : disable all formatting/strings 37 | #define X86_DASM_NLE : if not on a little-endian system 38 | */ 39 | 40 | #define BIT_MASK(__TYPE__, __ONE_COUNT__) \ 41 | ((__TYPE__) (-((__ONE_COUNT__) != 0))) \ 42 | & (((__TYPE__) -1) >> ((sizeof(__TYPE__) * CHAR_BIT) - (__ONE_COUNT__))) 43 | 44 | /**************************************************************************** 45 | 46 | x86 registers 47 | 48 | ****************************************************************************/ 49 | 50 | enum 51 | { 52 | /* 64-bit general-purpose registers */ 53 | X86_REG_RAX = 0, 54 | X86_REG_RCX, 55 | X86_REG_RDX, 56 | X86_REG_RBX, 57 | X86_REG_RSP, 58 | X86_REG_RBP, 59 | X86_REG_RSI, 60 | X86_REG_RDI, 61 | X86_REG_R8, 62 | X86_REG_R9, 63 | X86_REG_R10, 64 | X86_REG_R11, 65 | X86_REG_R12, 66 | X86_REG_R13, 67 | X86_REG_R14, 68 | X86_REG_R15, 69 | X86_REG_RIP, 70 | 71 | /* 32-bit general-purpose registers */ 72 | X86_REG_EAX, 73 | X86_REG_ECX, 74 | X86_REG_EDX, 75 | X86_REG_EBX, 76 | X86_REG_ESP, 77 | X86_REG_EBP, 78 | X86_REG_ESI, 79 | X86_REG_EDI, 80 | X86_REG_R8D, 81 | X86_REG_R9D, 82 | X86_REG_R10D, 83 | X86_REG_R11D, 84 | X86_REG_R12D, 85 | X86_REG_R13D, 86 | X86_REG_R14D, 87 | X86_REG_R15D, 88 | X86_REG_EIP, 89 | 90 | /* 16-bit general-purpose registers */ 91 | X86_REG_AX, 92 | X86_REG_CX, 93 | X86_REG_DX, 94 | X86_REG_BX, 95 | X86_REG_SP, 96 | X86_REG_BP, 97 | X86_REG_SI, 98 | X86_REG_DI, 99 | X86_REG_R8W, 100 | X86_REG_R9W, 101 | X86_REG_R10W, 102 | X86_REG_R11W, 103 | X86_REG_R12W, 104 | X86_REG_R13W, 105 | X86_REG_R14W, 106 | X86_REG_R15W, 107 | 108 | /* 8-bit general-purpose registers */ 109 | X86_REG_AL, 110 | X86_REG_CL, 111 | X86_REG_DL, 112 | X86_REG_BL, 113 | X86_REG_AH, /* not addressable in REX prefix instruction forms */ 114 | X86_REG_CH, /* not addressable in REX prefix instruction forms */ 115 | X86_REG_DH, /* not addressable in REX prefix instruction forms */ 116 | X86_REG_BH, /* not addressable in REX prefix instruction forms */ 117 | X86_REG_SPL, /* only addressable in REX prefix instruction forms */ 118 | X86_REG_BPL, /* only addressable in REX prefix instruction forms */ 119 | X86_REG_SIL, /* only addressable in REX prefix instruction forms */ 120 | X86_REG_DIL, /* only addressable in REX prefix instruction forms */ 121 | X86_REG_R8L, 122 | X86_REG_R9L, 123 | X86_REG_R10L, 124 | X86_REG_R11L, 125 | X86_REG_R12L, 126 | X86_REG_R13L, 127 | X86_REG_R14L, 128 | X86_REG_R15L, 129 | 130 | /* segment registers */ 131 | X86_REG_ES, /* ignored in long 64-bit mode */ 132 | X86_REG_CS, 133 | X86_REG_SS, /* ignored in long 64-bit mode */ 134 | X86_REG_DS, /* ignored in long 64-bit mode */ 135 | X86_REG_FS, 136 | X86_REG_GS, 137 | 138 | /* FPU x87 registers, FPR0-FPR7 */ 139 | X86_REG_ST0, 140 | X86_REG_ST1, 141 | X86_REG_ST2, 142 | X86_REG_ST3, 143 | X86_REG_ST4, 144 | X86_REG_ST5, 145 | X86_REG_ST6, 146 | X86_REG_ST7, 147 | 148 | /* MMX registers */ 149 | X86_REG_MM0, 150 | X86_REG_MM1, 151 | X86_REG_MM2, 152 | X86_REG_MM3, 153 | X86_REG_MM4, 154 | X86_REG_MM5, 155 | X86_REG_MM6, 156 | X86_REG_MM7, 157 | 158 | /* XMM registers */ 159 | X86_REG_XMM0, 160 | X86_REG_XMM1, 161 | X86_REG_XMM2, 162 | X86_REG_XMM3, 163 | X86_REG_XMM4, 164 | X86_REG_XMM5, 165 | X86_REG_XMM6, 166 | X86_REG_XMM7, 167 | X86_REG_XMM8, 168 | X86_REG_XMM9, 169 | X86_REG_XMM10, 170 | X86_REG_XMM11, 171 | X86_REG_XMM12, 172 | X86_REG_XMM13, 173 | X86_REG_XMM14, 174 | X86_REG_XMM15, 175 | X86_REG_XMM16, /* AVX-512 */ 176 | X86_REG_XMM17, /* AVX-512 */ 177 | X86_REG_XMM18, /* AVX-512 */ 178 | X86_REG_XMM19, /* AVX-512 */ 179 | X86_REG_XMM20, /* AVX-512 */ 180 | X86_REG_XMM21, /* AVX-512 */ 181 | X86_REG_XMM22, /* AVX-512 */ 182 | X86_REG_XMM23, /* AVX-512 */ 183 | X86_REG_XMM24, /* AVX-512 */ 184 | X86_REG_XMM25, /* AVX-512 */ 185 | X86_REG_XMM26, /* AVX-512 */ 186 | X86_REG_XMM27, /* AVX-512 */ 187 | X86_REG_XMM28, /* AVX-512 */ 188 | X86_REG_XMM29, /* AVX-512 */ 189 | X86_REG_XMM30, /* AVX-512 */ 190 | X86_REG_XMM31, /* AVX-512 */ 191 | 192 | /* YMM registers */ 193 | X86_REG_YMM0, 194 | X86_REG_YMM1, 195 | X86_REG_YMM2, 196 | X86_REG_YMM3, 197 | X86_REG_YMM4, 198 | X86_REG_YMM5, 199 | X86_REG_YMM6, 200 | X86_REG_YMM7, 201 | X86_REG_YMM8, 202 | X86_REG_YMM9, 203 | X86_REG_YMM10, 204 | X86_REG_YMM11, 205 | X86_REG_YMM12, 206 | X86_REG_YMM13, 207 | X86_REG_YMM14, 208 | X86_REG_YMM15, 209 | X86_REG_YMM16, /* AVX-512 */ 210 | X86_REG_YMM17, /* AVX-512 */ 211 | X86_REG_YMM18, /* AVX-512 */ 212 | X86_REG_YMM19, /* AVX-512 */ 213 | X86_REG_YMM20, /* AVX-512 */ 214 | X86_REG_YMM21, /* AVX-512 */ 215 | X86_REG_YMM22, /* AVX-512 */ 216 | X86_REG_YMM23, /* AVX-512 */ 217 | X86_REG_YMM24, /* AVX-512 */ 218 | X86_REG_YMM25, /* AVX-512 */ 219 | X86_REG_YMM26, /* AVX-512 */ 220 | X86_REG_YMM27, /* AVX-512 */ 221 | X86_REG_YMM28, /* AVX-512 */ 222 | X86_REG_YMM29, /* AVX-512 */ 223 | X86_REG_YMM30, /* AVX-512 */ 224 | X86_REG_YMM31, /* AVX-512 */ 225 | 226 | /* ZMM registers */ 227 | X86_REG_ZMM0, 228 | X86_REG_ZMM1, 229 | X86_REG_ZMM2, 230 | X86_REG_ZMM3, 231 | X86_REG_ZMM4, 232 | X86_REG_ZMM5, 233 | X86_REG_ZMM6, 234 | X86_REG_ZMM7, 235 | X86_REG_ZMM8, 236 | X86_REG_ZMM9, 237 | X86_REG_ZMM10, 238 | X86_REG_ZMM11, 239 | X86_REG_ZMM12, 240 | X86_REG_ZMM13, 241 | X86_REG_ZMM14, 242 | X86_REG_ZMM15, 243 | X86_REG_ZMM16, /* AVX-512 */ 244 | X86_REG_ZMM17, /* AVX-512 */ 245 | X86_REG_ZMM18, /* AVX-512 */ 246 | X86_REG_ZMM19, /* AVX-512 */ 247 | X86_REG_ZMM20, /* AVX-512 */ 248 | X86_REG_ZMM21, /* AVX-512 */ 249 | X86_REG_ZMM22, /* AVX-512 */ 250 | X86_REG_ZMM23, /* AVX-512 */ 251 | X86_REG_ZMM24, /* AVX-512 */ 252 | X86_REG_ZMM25, /* AVX-512 */ 253 | X86_REG_ZMM26, /* AVX-512 */ 254 | X86_REG_ZMM27, /* AVX-512 */ 255 | X86_REG_ZMM28, /* AVX-512 */ 256 | X86_REG_ZMM29, /* AVX-512 */ 257 | X86_REG_ZMM30, /* AVX-512 */ 258 | X86_REG_ZMM31, /* AVX-512 */ 259 | 260 | /* debug registers */ 261 | X86_REG_DR0, 262 | X86_REG_DR1, 263 | X86_REG_DR2, 264 | X86_REG_DR3, 265 | X86_REG_DR4, 266 | X86_REG_DR5, 267 | X86_REG_DR6, 268 | X86_REG_DR7, 269 | X86_REG_DR8, /* reserved: undefined opcode (#UD) exception */ 270 | X86_REG_DR9, /* reserved: undefined opcode (#UD) exception */ 271 | X86_REG_DR10, /* reserved: undefined opcode (#UD) exception */ 272 | X86_REG_DR11, /* reserved: undefined opcode (#UD) exception */ 273 | X86_REG_DR12, /* reserved: undefined opcode (#UD) exception */ 274 | X86_REG_DR13, /* reserved: undefined opcode (#UD) exception */ 275 | X86_REG_DR14, /* reserved: undefined opcode (#UD) exception */ 276 | X86_REG_DR15, /* reserved: undefined opcode (#UD) exception */ 277 | 278 | /* control registers */ 279 | X86_REG_CR0, 280 | X86_REG_CR1, /* reserved: undefined opcode (#UD) exception */ 281 | X86_REG_CR2, 282 | X86_REG_CR3, 283 | X86_REG_CR4, 284 | X86_REG_CR5, /* reserved: undefined opcode (#UD) exception */ 285 | X86_REG_CR6, /* reserved: undefined opcode (#UD) exception */ 286 | X86_REG_CR7, /* reserved: undefined opcode (#UD) exception */ 287 | X86_REG_CR8, 288 | X86_REG_CR9, /* reserved: undefined opcode (#UD) exception */ 289 | X86_REG_CR10, /* reserved: undefined opcode (#UD) exception */ 290 | X86_REG_CR11, /* reserved: undefined opcode (#UD) exception */ 291 | X86_REG_CR12, /* reserved: undefined opcode (#UD) exception */ 292 | X86_REG_CR13, /* reserved: undefined opcode (#UD) exception */ 293 | X86_REG_CR14, /* reserved: undefined opcode (#UD) exception */ 294 | X86_REG_CR15, /* reserved: undefined opcode (#UD) exception */ 295 | 296 | /* used only internally! */ 297 | X86_REG_GPR, 298 | X86_REG_NONE /* invalid or not present */ 299 | }; 300 | 301 | /**************************************************************************** 302 | 303 | x86 instruction sets 304 | 305 | ****************************************************************************/ 306 | 307 | enum 308 | { 309 | X86_ISET_NONE = 0, 310 | X86_ISET_GP, /* general-purpose instructions */ 311 | X86_ISET_BMI1, /* bit manipulation instructions */ 312 | X86_ISET_BMI2, 313 | X86_ISET_FPU, /* floating-point unit (x87 co-processor) instructions */ 314 | X86_ISET_MMX, /* single instruction, multiple data (SIMD) instructions */ 315 | X86_ISET_SSE, 316 | X86_ISET_SSE2, 317 | X86_ISET_SSE3, 318 | X86_ISET_SSSE3, 319 | X86_ISET_SSE4, 320 | X86_ISET_SSE41, 321 | X86_ISET_SSE42, 322 | X86_ISET_SSE4A, 323 | X86_ISET_AESNI, /* advanced encryption standard new instructions */ 324 | X86_ISET_VMX, /* intel virtual-machine extension instructions */ 325 | X86_ISET_SVM, /* amd secure virtual machine instructions */ 326 | X86_ISET_FMA, /* fused multiply add (fma) instructions */ 327 | X86_ISET_FMA4, 328 | X86_ISET_F16C, 329 | X86_ISET_PCLMULQDQ, 330 | X86_ISET_ADX, 331 | X86_ISET_AVX, /* advanced vector extension instructions */ 332 | X86_ISET_AVX2, 333 | X86_ISET_AVX512, 334 | X86_ISET_XOP, 335 | X86_ISET_3DNOW, 336 | X86_ISET_TSX, 337 | X86_ISET_CET, /* control-flow enforcement technology */ 338 | X86_ISET_UNKNOWN 339 | }; 340 | 341 | /**************************************************************************** 342 | 343 | x86 mnemonics 344 | 345 | ****************************************************************************/ 346 | 347 | enum 348 | { 349 | X86_MN_INVALID = 0, 350 | 351 | X86_MN_AAA, 352 | X86_MN_AAD, 353 | X86_MN_AAM, 354 | X86_MN_AAS, 355 | X86_MN_ADC, 356 | X86_MN_ADCX, 357 | X86_MN_ADD, 358 | X86_MN_ADDPD, 359 | X86_MN_ADDPS, 360 | X86_MN_ADDSD, 361 | X86_MN_ADDSS, 362 | X86_MN_ADDSUBPD, 363 | X86_MN_ADDSUBPS, 364 | X86_MN_ADOX, 365 | X86_MN_ADX, 366 | X86_MN_AESDEC, 367 | X86_MN_AESDECLAST, 368 | X86_MN_AESENC, 369 | X86_MN_AESENCLAST, 370 | X86_MN_AESIMC, 371 | X86_MN_AESKEYGEN, 372 | X86_MN_AESKEYGENASSIST, 373 | X86_MN_AMX, 374 | X86_MN_AND, 375 | X86_MN_ANDN, 376 | X86_MN_ANDNPD, 377 | X86_MN_ANDNPS, 378 | X86_MN_ANDPD, 379 | X86_MN_ANDPS, 380 | X86_MN_ARPL, 381 | X86_MN_BEXTR, 382 | X86_MN_BLENDPD, 383 | X86_MN_BLENDPS, 384 | X86_MN_BLENDVPD, 385 | X86_MN_BLENDVPS, 386 | X86_MN_BLSI, 387 | X86_MN_BLSMSK, 388 | X86_MN_BLSR, 389 | X86_MN_BOUND, 390 | X86_MN_BROADCASTF128, 391 | X86_MN_BROADCASTI128, 392 | X86_MN_BROADCASTSD, 393 | X86_MN_BROADCASTSS, 394 | X86_MN_BSF, 395 | X86_MN_BSR, 396 | X86_MN_BSWAP, 397 | X86_MN_BT, 398 | X86_MN_BTC, 399 | X86_MN_BTR, 400 | X86_MN_BTS, 401 | X86_MN_BZHI, 402 | X86_MN_CALL, 403 | X86_MN_CALLF, 404 | X86_MN_CBW, 405 | X86_MN_CDQ, 406 | X86_MN_CDQE, 407 | X86_MN_CLAC, 408 | X86_MN_CLC, 409 | X86_MN_CLD, 410 | X86_MN_CLFLUSH, 411 | X86_MN_CLGI, 412 | X86_MN_CLI, 413 | X86_MN_CLTS, 414 | X86_MN_CMC, 415 | X86_MN_CMOVA, 416 | X86_MN_CMOVNC, 417 | X86_MN_CMOVC, 418 | X86_MN_CMOVNA, 419 | X86_MN_CMOVZ, 420 | X86_MN_CMOVG, 421 | X86_MN_CMOVNL, 422 | X86_MN_CMOVL, 423 | X86_MN_CMOVNG, 424 | X86_MN_CMOVNZ, 425 | X86_MN_CMOVNO, 426 | X86_MN_CMOVNP, 427 | X86_MN_CMOVNS, 428 | X86_MN_CMOVO, 429 | X86_MN_CMOVP, 430 | X86_MN_CMOVPO, 431 | X86_MN_CMOVS, 432 | X86_MN_CMP, 433 | X86_MN_CMPPD, 434 | X86_MN_CMPPS, 435 | X86_MN_CMPS, 436 | X86_MN_CMPSB, 437 | X86_MN_CMPSW, 438 | X86_MN_CMPSQ, 439 | X86_MN_CMPSD, 440 | X86_MN_CMPSS, 441 | X86_MN_CMPXCHG, 442 | X86_MN_CMPXCHG16B, 443 | X86_MN_CMPXCHG8B, 444 | X86_MN_COMISD, 445 | X86_MN_COMISS, 446 | X86_MN_CPUID, 447 | X86_MN_CQO, 448 | X86_MN_CRC32, 449 | X86_MN_CVTDQ2PD, 450 | X86_MN_CVTDQ2PS, 451 | X86_MN_CVTPD2DQ, 452 | X86_MN_CVTPD2PI, 453 | X86_MN_CVTPD2PS, 454 | X86_MN_CVTPH2PS, 455 | X86_MN_CVTPI2PD, 456 | X86_MN_CVTPI2PS, 457 | X86_MN_CVTPS2DQ, 458 | X86_MN_CVTPS2PD, 459 | X86_MN_CVTPS2PH, 460 | X86_MN_CVTPS2PI, 461 | X86_MN_CVTSD2SI, 462 | X86_MN_CVTSD2SS, 463 | X86_MN_CVTSI2SD, 464 | X86_MN_CVTSI2SS, 465 | X86_MN_CVTSS2SD, 466 | X86_MN_CVTSS2SI, 467 | X86_MN_CVTTPD2DQ, 468 | X86_MN_CVTTPD2PI, 469 | X86_MN_CVTTPS2DQ, 470 | X86_MN_CVTTPS2PI, 471 | X86_MN_CVTTSD2SI, 472 | X86_MN_CVTTSS2SI, 473 | X86_MN_CWD, 474 | X86_MN_CWDE, 475 | X86_MN_DAA, 476 | X86_MN_DAS, 477 | X86_MN_DEC, 478 | X86_MN_DIV, 479 | X86_MN_DIVPD, 480 | X86_MN_DIVPS, 481 | X86_MN_DIVSD, 482 | X86_MN_DIVSS, 483 | X86_MN_DPPD, 484 | X86_MN_DPPS, 485 | X86_MN_EMMS, 486 | X86_MN_ENTER, 487 | X86_MN_ENDBR32, 488 | X86_MN_ENDBR64, 489 | X86_MN_EXTRACTF128, 490 | X86_MN_EXTRACTI128, 491 | X86_MN_EXTRACTPS, 492 | X86_MN_EXTRQ, 493 | X86_MN_F2XM1, 494 | X86_MN_FABS, 495 | X86_MN_FADD, 496 | X86_MN_FADDP, 497 | X86_MN_FBLD, 498 | X86_MN_FBSTP, 499 | X86_MN_FCHS, 500 | X86_MN_FCLEX, 501 | X86_MN_FCMOVB, 502 | X86_MN_FCMOVBE, 503 | X86_MN_FCMOVE, 504 | X86_MN_FCMOVNB, 505 | X86_MN_FCMOVNBE, 506 | X86_MN_FCMOVNE, 507 | X86_MN_FCMOVNU, 508 | X86_MN_FCMOVU, 509 | X86_MN_FCOM, 510 | X86_MN_FCOM2, 511 | X86_MN_FCOMI, 512 | X86_MN_FCOMIP, 513 | X86_MN_FCOMP, 514 | X86_MN_FCOMP3, 515 | X86_MN_FCOMP5, 516 | X86_MN_FCOMPP, 517 | X86_MN_FCOS, 518 | X86_MN_FDECSTP, 519 | X86_MN_FDIV, 520 | X86_MN_FDIVP, 521 | X86_MN_FDIVR, 522 | X86_MN_FDIVRP, 523 | X86_MN_FEMMS, 524 | X86_MN_FFREE, 525 | X86_MN_FIADD, 526 | X86_MN_FICOM, 527 | X86_MN_FICOMP, 528 | X86_MN_FIDIV, 529 | X86_MN_FIDIVR, 530 | X86_MN_FILD, 531 | X86_MN_FIMUL, 532 | X86_MN_FINCSTP, 533 | X86_MN_FINIT, 534 | X86_MN_FIST, 535 | X86_MN_FISTP, 536 | X86_MN_FISTTP, 537 | X86_MN_FISUB, 538 | X86_MN_FISUBR, 539 | X86_MN_FLD, 540 | X86_MN_FLD1, 541 | X86_MN_FLDCW, 542 | X86_MN_FLDENV, 543 | X86_MN_FLDL2E, 544 | X86_MN_FLDL2T, 545 | X86_MN_FLDLG2, 546 | X86_MN_FLDLN2, 547 | X86_MN_FLDPI, 548 | X86_MN_FLDZ, 549 | X86_MN_FMADDPD, 550 | X86_MN_FMADD132PD, 551 | X86_MN_FMADD132PS, 552 | X86_MN_FMADD132SD, 553 | X86_MN_FMADD132SS, 554 | X86_MN_FMADD213PD, 555 | X86_MN_FMADD213PS, 556 | X86_MN_FMADD213SD, 557 | X86_MN_FMADD213SS, 558 | X86_MN_FMADD231PD, 559 | X86_MN_FMADD231PS, 560 | X86_MN_FMADD231SD, 561 | X86_MN_FMADD231SS, 562 | X86_MN_FMADDSUB132PD, 563 | X86_MN_FMADDSUB132PS, 564 | X86_MN_FMADDSUB213PD, 565 | X86_MN_FMADDSUB213PS, 566 | X86_MN_FMADDSUB231PD, 567 | X86_MN_FMADDSUB231PS, 568 | X86_MN_FMSUB132PD, 569 | X86_MN_FMSUB132PS, 570 | X86_MN_FMSUB132SD, 571 | X86_MN_FMSUB132SS, 572 | X86_MN_FMSUB213PD, 573 | X86_MN_FMSUB213PS, 574 | X86_MN_FMSUB213SD, 575 | X86_MN_FMSUB213SS, 576 | X86_MN_FMSUB231PD, 577 | X86_MN_FMSUB231PS, 578 | X86_MN_FMSUB231SD, 579 | X86_MN_FMSUB231SS, 580 | X86_MN_FMSUBADD132PD, 581 | X86_MN_FMSUBADD132PS, 582 | X86_MN_FMSUBADD213PD, 583 | X86_MN_FMSUBADD213PS, 584 | X86_MN_FMSUBADD231PD, 585 | X86_MN_FMSUBADD231PS, 586 | X86_MN_FMUL, 587 | X86_MN_FMULP, 588 | X86_MN_FNCLEX, 589 | X86_MN_FNDISI, 590 | X86_MN_FNENI, 591 | X86_MN_FNINIT, 592 | X86_MN_FNMADD132PD, 593 | X86_MN_FNMADD132PS, 594 | X86_MN_FNMADD132SD, 595 | X86_MN_FNMADD132SS, 596 | X86_MN_FNMADD213PD, 597 | X86_MN_FNMADD213PS, 598 | X86_MN_FNMADD213SD, 599 | X86_MN_FNMADD213SS, 600 | X86_MN_FNMADD231PD, 601 | X86_MN_FNMADD231PS, 602 | X86_MN_FNMADD231SD, 603 | X86_MN_FNMADD231SS, 604 | X86_MN_FNMSUB132PD, 605 | X86_MN_FNMSUB132PS, 606 | X86_MN_FNMSUB132SD, 607 | X86_MN_FNMSUB132SS, 608 | X86_MN_FNMSUB213PD, 609 | X86_MN_FNMSUB213PS, 610 | X86_MN_FNMSUB213SD, 611 | X86_MN_FNMSUB213SS, 612 | X86_MN_FNMSUB231PD, 613 | X86_MN_FNMSUB231PS, 614 | X86_MN_FNMSUB231SD, 615 | X86_MN_FNMSUB231SS, 616 | X86_MN_FNOP, 617 | X86_MN_FNSAVE, 618 | X86_MN_FNSETPM, 619 | X86_MN_FNSTCW, 620 | X86_MN_FNSTENV, 621 | X86_MN_FNSTSW, 622 | X86_MN_FPATAN, 623 | X86_MN_FPREM, 624 | X86_MN_FPREM1, 625 | X86_MN_FPTAN, 626 | X86_MN_FRNDINT, 627 | X86_MN_FRSTOR, 628 | X86_MN_FSAVE, 629 | X86_MN_FSCALE, 630 | X86_MN_FSIN, 631 | X86_MN_FSINCOS, 632 | X86_MN_FSQRT, 633 | X86_MN_FST, 634 | X86_MN_FSTCW, 635 | X86_MN_FSTENV, 636 | X86_MN_FSTP, 637 | X86_MN_FSTP1, 638 | X86_MN_FSTP8, 639 | X86_MN_FSTP9, 640 | X86_MN_FSTSW, 641 | X86_MN_FSUB, 642 | X86_MN_FSUBP, 643 | X86_MN_FSUBR, 644 | X86_MN_FSUBRP, 645 | X86_MN_FTST, 646 | X86_MN_FUCOM, 647 | X86_MN_FUCOMI, 648 | X86_MN_FUCOMIP, 649 | X86_MN_FUCOMP, 650 | X86_MN_FUCOMPP, 651 | X86_MN_FWAIT, 652 | X86_MN_FXAM, 653 | X86_MN_FXCH, 654 | X86_MN_FXRSTOR, 655 | X86_MN_FXRSTOR64, 656 | X86_MN_FXSAVE, 657 | X86_MN_FXSAVE64, 658 | X86_MN_FXTRACT, 659 | X86_MN_FYL2X, 660 | X86_MN_FYL2XP1, 661 | X86_MN_GATHERDD, 662 | X86_MN_GATHERDPD, 663 | X86_MN_GATHERDPS, 664 | X86_MN_GATHERDQ, 665 | X86_MN_GATHERQD, 666 | X86_MN_GATHERQPD, 667 | X86_MN_GATHERQPS, 668 | X86_MN_GATHERQQ, 669 | X86_MN_GETSEC, 670 | X86_MN_HADDPD, 671 | X86_MN_HADDPS, 672 | X86_MN_HINTNOP, 673 | X86_MN_HLT, 674 | X86_MN_HSUBPD, 675 | X86_MN_HSUBPS, 676 | X86_MN_ICEBP, 677 | X86_MN_IDIV, 678 | X86_MN_IMUL, 679 | X86_MN_IN, 680 | X86_MN_INC, 681 | X86_MN_INS, 682 | X86_MN_INSB, 683 | X86_MN_INSW, 684 | X86_MN_INSD, 685 | X86_MN_INSERTF128, 686 | X86_MN_INSERTI128, 687 | X86_MN_INSERTPS, 688 | X86_MN_INSERTQ, 689 | X86_MN_INT, 690 | X86_MN_INT3, 691 | X86_MN_INTO, 692 | X86_MN_INVD, 693 | X86_MN_INVEPT, 694 | X86_MN_INVLPG, 695 | X86_MN_INVLPGA, 696 | X86_MN_INVPCID, 697 | X86_MN_INVVPID, 698 | X86_MN_IRET, 699 | X86_MN_IRETW, 700 | X86_MN_IRETD, 701 | X86_MN_IRETQ, 702 | X86_MN_JA, 703 | X86_MN_JC, 704 | X86_MN_JNG, 705 | X86_MN_JZ, 706 | X86_MN_JG, 707 | X86_MN_JNL, 708 | X86_MN_JL, 709 | X86_MN_JNA, 710 | X86_MN_JMP, 711 | X86_MN_JMPF, 712 | X86_MN_JNC, 713 | X86_MN_JNZ, 714 | X86_MN_JNO, 715 | X86_MN_JNP, 716 | X86_MN_JNS, 717 | X86_MN_JO, 718 | X86_MN_JP, 719 | X86_MN_JS, 720 | X86_MN_JCXZ, 721 | X86_MN_JECXZ, 722 | X86_MN_JRCXZ, 723 | X86_MN_LAHF, 724 | X86_MN_LAR, 725 | X86_MN_LDDQU, 726 | X86_MN_LDMXCSR, 727 | X86_MN_LDS, 728 | X86_MN_LEA, 729 | X86_MN_LEAVE, 730 | X86_MN_LES, 731 | X86_MN_LFENCE, 732 | X86_MN_LFS, 733 | X86_MN_LGDT, 734 | X86_MN_LGS, 735 | X86_MN_LIDT, 736 | X86_MN_LLDT, 737 | X86_MN_LMSW, 738 | X86_MN_LODS, 739 | X86_MN_LODSB, 740 | X86_MN_LODSW, 741 | X86_MN_LODSD, 742 | X86_MN_LODSQ, 743 | X86_MN_LOOP, 744 | X86_MN_LOOPZ, 745 | X86_MN_LOOPNZ, 746 | X86_MN_LSL, 747 | X86_MN_LSS, 748 | X86_MN_LTR, 749 | X86_MN_LZCNT, 750 | X86_MN_MASKMOVDQU, 751 | X86_MN_MASKMOVPD, 752 | X86_MN_MASKMOVPS, 753 | X86_MN_MASKMOVQ, 754 | X86_MN_MAXPD, 755 | X86_MN_MAXPS, 756 | X86_MN_MAXSD, 757 | X86_MN_MAXSS, 758 | X86_MN_MFENCE, 759 | X86_MN_MINPD, 760 | X86_MN_MINPS, 761 | X86_MN_MINSD, 762 | X86_MN_MINSS, 763 | X86_MN_MONITOR, 764 | X86_MN_MOV, 765 | X86_MN_MOVAPD, 766 | X86_MN_MOVAPS, 767 | X86_MN_MOVBE, 768 | X86_MN_MOVD, 769 | X86_MN_MOVDDUP, 770 | X86_MN_MOVDQ2Q, 771 | X86_MN_MOVDQA, 772 | X86_MN_MOVDQU, 773 | X86_MN_MOVHLPS, 774 | X86_MN_MOVHPD, 775 | X86_MN_MOVHPS, 776 | X86_MN_MOVLHPS, 777 | X86_MN_MOVLPD, 778 | X86_MN_MOVLPS, 779 | X86_MN_MOVMSKPD, 780 | X86_MN_MOVMSKPS, 781 | X86_MN_MOVNTDQ, 782 | X86_MN_MOVNTDQA, 783 | X86_MN_MOVNTI, 784 | X86_MN_MOVNTPD, 785 | X86_MN_MOVNTSS, 786 | X86_MN_MOVNTSD, 787 | X86_MN_MOVNTPS, 788 | X86_MN_MOVNTQ, 789 | X86_MN_MOVQ, 790 | X86_MN_MOVQ2DQ, 791 | X86_MN_MOVS, 792 | X86_MN_MOVSB, 793 | X86_MN_MOVSW, 794 | X86_MN_MOVSD, 795 | X86_MN_MOVSQ, 796 | X86_MN_MOVSHDUP, 797 | X86_MN_MOVSLDUP, 798 | X86_MN_MOVSS, 799 | X86_MN_MOVSX, 800 | X86_MN_MOVSXD, 801 | X86_MN_MOVUPD, 802 | X86_MN_MOVUPS, 803 | X86_MN_MOVZX, 804 | X86_MN_MPSADBW, 805 | X86_MN_MUL, 806 | X86_MN_MULPD, 807 | X86_MN_MULPS, 808 | X86_MN_MULSD, 809 | X86_MN_MULSS, 810 | X86_MN_MULX, 811 | X86_MN_MWAIT, 812 | X86_MN_NEG, 813 | X86_MN_NOP, 814 | X86_MN_NOT, 815 | X86_MN_OR, 816 | X86_MN_ORPD, 817 | X86_MN_ORPS, 818 | X86_MN_OUT, 819 | X86_MN_OUTS, 820 | X86_MN_OUTSB, 821 | X86_MN_OUTSW, 822 | X86_MN_OUTSD, 823 | X86_MN_PABSB, 824 | X86_MN_PABSD, 825 | X86_MN_PABSW, 826 | X86_MN_PACKSSDB, 827 | X86_MN_PACKSSDW, 828 | X86_MN_PACKSSWB, 829 | X86_MN_PACKUSDB, 830 | X86_MN_PACKUSDW, 831 | X86_MN_PACKUSWB, 832 | X86_MN_PADDB, 833 | X86_MN_PADDD, 834 | X86_MN_PADDQ, 835 | X86_MN_PADDSB, 836 | X86_MN_PADDSW, 837 | X86_MN_PADDUSB, 838 | X86_MN_PADDUSW, 839 | X86_MN_PADDW, 840 | X86_MN_PALIGNR, 841 | X86_MN_PAND, 842 | X86_MN_PANDN, 843 | X86_MN_PAUSE, 844 | X86_MN_PAVGB, 845 | X86_MN_PAVGW, 846 | X86_MN_PBLENDD, 847 | X86_MN_PBLENDVB, 848 | X86_MN_PBLENDW, 849 | X86_MN_PBROADCASTB, 850 | X86_MN_PBROADCASTD, 851 | X86_MN_PBROADCASTQ, 852 | X86_MN_PBROADCASTW, 853 | X86_MN_PCLMULQDQ, 854 | X86_MN_PCMPEQB, 855 | X86_MN_PCMPEQD, 856 | X86_MN_PCMPEQQ, 857 | X86_MN_PCMPEQW, 858 | X86_MN_PCMPESTRI, 859 | X86_MN_PCMPESTRM, 860 | X86_MN_PCMPGTB, 861 | X86_MN_PCMPGTD, 862 | X86_MN_PCMPGTQ, 863 | X86_MN_PCMPGTW, 864 | X86_MN_PCMPISTRI, 865 | X86_MN_PCMPISTRM, 866 | X86_MN_PDEP, 867 | X86_MN_PERM2F128, 868 | X86_MN_PERM2I128, 869 | X86_MN_PERMD, 870 | X86_MN_PERMILPD, 871 | X86_MN_PERMILPS, 872 | X86_MN_PERMPD, 873 | X86_MN_PERMPS, 874 | X86_MN_PERMQ, 875 | X86_MN_PEXT, 876 | X86_MN_PEXTRB, 877 | X86_MN_PEXTRD, 878 | X86_MN_PEXTRQ, 879 | X86_MN_PEXTRW, 880 | X86_MN_PFRCPIT2, 881 | X86_MN_PHADDD, 882 | X86_MN_PHADDSW, 883 | X86_MN_PHADDW, 884 | X86_MN_PHMINPOSUW, 885 | X86_MN_PHSUBD, 886 | X86_MN_PHSUBSW, 887 | X86_MN_PHSUBW, 888 | X86_MN_PINSRB, 889 | X86_MN_PINSRD, 890 | X86_MN_PINSRQ, 891 | X86_MN_PINSRW, 892 | X86_MN_PMADDUBSW, 893 | X86_MN_PMADDWD, 894 | X86_MN_PMADDWS, 895 | X86_MN_PMASKMOVD, 896 | X86_MN_PMASKMOVQ, 897 | X86_MN_PMAXSB, 898 | X86_MN_PMAXSD, 899 | X86_MN_PMAXSW, 900 | X86_MN_PMAXUB, 901 | X86_MN_PMAXUD, 902 | X86_MN_PMAXUW, 903 | X86_MN_PMINS, 904 | X86_MN_PMINSB, 905 | X86_MN_PMINSD, 906 | X86_MN_PMINSW, 907 | X86_MN_PMINUB, 908 | X86_MN_PMINUD, 909 | X86_MN_PMINUW, 910 | X86_MN_PMOVMSKB, 911 | X86_MN_PMOVSX, 912 | X86_MN_PMOVSXBD, 913 | X86_MN_PMOVSXBQ, 914 | X86_MN_PMOVSXBW, 915 | X86_MN_PMOVSXDQ, 916 | X86_MN_PMOVSXWD, 917 | X86_MN_PMOVSXWQ, 918 | X86_MN_PMOVZX, 919 | X86_MN_PMOVZXBD, 920 | X86_MN_PMOVZXBQ, 921 | X86_MN_PMOVZXBW, 922 | X86_MN_PMOVZXDQ, 923 | X86_MN_PMOVZXWD, 924 | X86_MN_PMOVZXWQ, 925 | X86_MN_PMUL, 926 | X86_MN_PMULDQ, 927 | X86_MN_PMULHRSW, 928 | X86_MN_PMULHUW, 929 | X86_MN_PMULHW, 930 | X86_MN_PMULLD, 931 | X86_MN_PMULLW, 932 | X86_MN_PMULUDQ, 933 | X86_MN_POP, 934 | X86_MN_POPA, 935 | X86_MN_POPAD, 936 | X86_MN_POPCNT, 937 | X86_MN_POPF, 938 | X86_MN_POPFD, 939 | X86_MN_POPFQ, 940 | X86_MN_POR, 941 | X86_MN_PREFETCH, 942 | X86_MN_PREFETCHWT1, 943 | X86_MN_PREFETCHW, 944 | X86_MN_PREFETCHT0, 945 | X86_MN_PREFETCHT1, 946 | X86_MN_PREFETCHT2, 947 | X86_MN_PREFETCHNTA, 948 | X86_MN_PSADBW, 949 | X86_MN_PSHUFB, 950 | X86_MN_PSHUFD, 951 | X86_MN_PSHUFHW, 952 | X86_MN_PSHUFLW, 953 | X86_MN_PSHUFW, 954 | X86_MN_PSIGN, 955 | X86_MN_PSIGNB, 956 | X86_MN_PSIGND, 957 | X86_MN_PSIGNW, 958 | X86_MN_PSLLD, 959 | X86_MN_PSLLDQ, 960 | X86_MN_PSLLQ, 961 | X86_MN_PSLLVD, 962 | X86_MN_PSLLVQ, 963 | X86_MN_PSLLW, 964 | X86_MN_PSRAD, 965 | X86_MN_PSRAVD, 966 | X86_MN_PSRAW, 967 | X86_MN_PSRLD, 968 | X86_MN_PSRLDQ, 969 | X86_MN_PSRLQ, 970 | X86_MN_PSRLVD, 971 | X86_MN_PSRLVQ, 972 | X86_MN_PSRLW, 973 | X86_MN_PSUB, 974 | X86_MN_PSUBB, 975 | X86_MN_PSUBD, 976 | X86_MN_PSUBQ, 977 | X86_MN_PSUBSB, 978 | X86_MN_PSUBSW, 979 | X86_MN_PSUBUSB, 980 | X86_MN_PSUBUSW, 981 | X86_MN_PSUBW, 982 | X86_MN_PTEST, 983 | X86_MN_PTWRITE, 984 | X86_MN_PUNPCKHBW, 985 | X86_MN_PUNPCKHDQ, 986 | X86_MN_PUNPCKHQDQ, 987 | X86_MN_PUNPCKHWD, 988 | X86_MN_PUNPCKLBW, 989 | X86_MN_PUNPCKLDQ, 990 | X86_MN_PUNPCKLQDQ, 991 | X86_MN_PUNPCKLWD, 992 | X86_MN_PUSH, 993 | X86_MN_PUSHA, 994 | X86_MN_PUSHAD, 995 | X86_MN_PUSHF, 996 | X86_MN_PUSHFD, 997 | X86_MN_PUSHFQ, 998 | X86_MN_PXOR, 999 | X86_MN_RCL, 1000 | X86_MN_RCPPS, 1001 | X86_MN_RCPSS, 1002 | X86_MN_RCR, 1003 | X86_MN_RDFSBASE, 1004 | X86_MN_RDGSBASE, 1005 | X86_MN_RDMSR, 1006 | X86_MN_RDPMC, 1007 | X86_MN_RDRAND, 1008 | X86_MN_RDSEED, 1009 | X86_MN_RDSSPD, 1010 | X86_MN_RDSSPQ, 1011 | X86_MN_RDTSC, 1012 | X86_MN_RDTSCP, 1013 | X86_MN_RETF, 1014 | X86_MN_RETN, 1015 | X86_MN_ROL, 1016 | X86_MN_ROR, 1017 | X86_MN_RORX, 1018 | X86_MN_ROUND, 1019 | X86_MN_ROUNDPD, 1020 | X86_MN_ROUNDPS, 1021 | X86_MN_ROUNDSD, 1022 | X86_MN_ROUNDSS, 1023 | X86_MN_RSM, 1024 | X86_MN_RSQRTPS, 1025 | X86_MN_RSQRTSS, 1026 | X86_MN_SAHF, 1027 | X86_MN_SAL, 1028 | X86_MN_SALC, 1029 | X86_MN_SAR, 1030 | X86_MN_SARX, 1031 | X86_MN_SBB, 1032 | X86_MN_SCAS, 1033 | X86_MN_SCASB, 1034 | X86_MN_SCASW, 1035 | X86_MN_SCASD, 1036 | X86_MN_SCASQ, 1037 | X86_MN_SETA, 1038 | X86_MN_SETC, 1039 | X86_MN_SETNC, 1040 | X86_MN_SETZ, 1041 | X86_MN_SETG, 1042 | X86_MN_SETNG, 1043 | X86_MN_SETL, 1044 | X86_MN_SETNL, 1045 | X86_MN_SETNA, 1046 | X86_MN_SETNZ, 1047 | X86_MN_SETNO, 1048 | X86_MN_SETNP, 1049 | X86_MN_SETNS, 1050 | X86_MN_SETO, 1051 | X86_MN_SETP, 1052 | X86_MN_SETPO, 1053 | X86_MN_SETS, 1054 | X86_MN_SFENCE, 1055 | X86_MN_SGDT, 1056 | X86_MN_SHL, 1057 | X86_MN_SHLD, 1058 | X86_MN_SHLX, 1059 | X86_MN_SHR, 1060 | X86_MN_SHRD, 1061 | X86_MN_SHRX, 1062 | X86_MN_SHUFPD, 1063 | X86_MN_SHUFPS, 1064 | X86_MN_SIDT, 1065 | X86_MN_SKINIT, 1066 | X86_MN_SLDT, 1067 | X86_MN_SMSW, 1068 | X86_MN_SQRT, 1069 | X86_MN_SQRTPD, 1070 | X86_MN_SQRTPS, 1071 | X86_MN_SQRTSD, 1072 | X86_MN_SQRTSS, 1073 | X86_MN_STAC, 1074 | X86_MN_STC, 1075 | X86_MN_STD, 1076 | X86_MN_STGI, 1077 | X86_MN_STI, 1078 | X86_MN_STMXCSR, 1079 | X86_MN_STOS, 1080 | X86_MN_STOSB, 1081 | X86_MN_STOSW, 1082 | X86_MN_STOSD, 1083 | X86_MN_STOSQ, 1084 | X86_MN_STR, 1085 | X86_MN_SUB, 1086 | X86_MN_SUBPD, 1087 | X86_MN_SUBPS, 1088 | X86_MN_SUBSD, 1089 | X86_MN_SUBSS, 1090 | X86_MN_SWAPGS, 1091 | X86_MN_SYSCALL, 1092 | X86_MN_SYSENTER, 1093 | X86_MN_SYSEXIT, 1094 | X86_MN_SYSRET, 1095 | X86_MN_TEST, 1096 | X86_MN_TESTPD, 1097 | X86_MN_TESTPS, 1098 | X86_MN_TZCNT, 1099 | X86_MN_UCOMISD, 1100 | X86_MN_UCOMISS, 1101 | X86_MN_UD, 1102 | X86_MN_UD1, 1103 | X86_MN_UD2, 1104 | X86_MN_UNPCKHPD, 1105 | X86_MN_UNPCKHPS, 1106 | X86_MN_UNPCKLPD, 1107 | X86_MN_UNPCKLPS, 1108 | X86_MN_VERR, 1109 | X86_MN_VERW, 1110 | X86_MN_VMCALL, 1111 | X86_MN_VMCLEAR, 1112 | X86_MN_VMFUNC, 1113 | X86_MN_VMLAUNCH, 1114 | X86_MN_VMLOAD, 1115 | X86_MN_VMPTRLD, 1116 | X86_MN_VMPTRST, 1117 | X86_MN_VMREAD, 1118 | X86_MN_VMRESUME, 1119 | X86_MN_VMRUN, 1120 | X86_MN_VMSAVE, 1121 | X86_MN_VMWRITE, 1122 | X86_MN_VMXOFF, 1123 | X86_MN_VMXON, 1124 | X86_MN_WAIT, 1125 | X86_MN_WBINVD, 1126 | X86_MN_WRFSBASE, 1127 | X86_MN_WRGSBASE, 1128 | X86_MN_WRMSR, 1129 | X86_MN_XADD, 1130 | X86_MN_XCHG, 1131 | X86_MN_XEND, 1132 | X86_MN_XGETBV, 1133 | X86_MN_XLAT, 1134 | X86_MN_XOR, 1135 | X86_MN_XORPD, 1136 | X86_MN_XORPS, 1137 | X86_MN_XORSS, 1138 | X86_MN_XRSTOR, 1139 | X86_MN_XRSTOR64, 1140 | X86_MN_XRSTORS, 1141 | X86_MN_XRSTORS64, 1142 | X86_MN_XSAVE, 1143 | X86_MN_XSAVE64, 1144 | X86_MN_XSAVEC, 1145 | X86_MN_XSAVEC64, 1146 | X86_MN_XSAVES, 1147 | X86_MN_XSAVES64, 1148 | X86_MN_XSAVEOPT, 1149 | X86_MN_XSAVEOPT64, 1150 | X86_MN_XSETBV, 1151 | X86_MN_XTEST, 1152 | /* XOP */ 1153 | X86_MN_VPMACSSWW, 1154 | X86_MN_VPMACSSWD, 1155 | X86_MN_VPMACSSDQL, 1156 | X86_MN_VPMACSSDD, 1157 | X86_MN_VPMACSSDQH, 1158 | X86_MN_VPMACSWW, 1159 | X86_MN_VPMACSWD, 1160 | X86_MN_VPMACSDQL, 1161 | X86_MN_VPMACSDD, 1162 | X86_MN_VPMACSDQH, 1163 | X86_MN_VPMADCSSWD, 1164 | X86_MN_VPMADCSWD, 1165 | X86_MN_VPROTB, 1166 | X86_MN_VPROTW, 1167 | X86_MN_VPROTD, 1168 | X86_MN_VPROTQ, 1169 | X86_MN_VPCOMB, 1170 | X86_MN_VPCOMW, 1171 | X86_MN_VPCOMD, 1172 | X86_MN_VPCOMQ, 1173 | X86_MN_VPCOMUB, 1174 | X86_MN_VPCOMUW, 1175 | X86_MN_VPCOMUD, 1176 | X86_MN_VPCOMUQ, 1177 | X86_MN_VPPERM, 1178 | X86_MN_VPCMOV, 1179 | X86_MN_VFRCZPS, 1180 | X86_MN_VFRCZPD, 1181 | X86_MN_VFRCZSS, 1182 | X86_MN_VFRCZSD, 1183 | X86_MN_VPHADDBW, 1184 | X86_MN_VPHADDBD, 1185 | X86_MN_VPHADDBQ, 1186 | X86_MN_VPHADDWD, 1187 | X86_MN_VPHADDWQ, 1188 | X86_MN_VPHADDDQ, 1189 | X86_MN_VPHADDUBWD, 1190 | X86_MN_VPHADDUBD, 1191 | X86_MN_VPHADDUBQ, 1192 | X86_MN_VPHADDUWD, 1193 | X86_MN_VPHADDUWQ, 1194 | X86_MN_VPHADDUDQ, 1195 | X86_MN_VPHSUBBW, 1196 | X86_MN_VPHSUBWD, 1197 | X86_MN_VPHSUBDQ, 1198 | X86_MN_VZEROUPPER, 1199 | X86_MN_VZEROALL, 1200 | X86_MN_BLCFILL, 1201 | X86_MN_BLSFILL, 1202 | X86_MN_BLCS, 1203 | X86_MN_TZMSK, 1204 | X86_MN_BLCIC, 1205 | X86_MN_BLCSIC, 1206 | X86_MN_T1MSKC, 1207 | X86_MN_BLCMSK, 1208 | X86_MN_LLWPCB, 1209 | X86_MN_SLWPCB, 1210 | X86_MN_VPSHLB, 1211 | X86_MN_VPSHLW, 1212 | X86_MN_VPSHLD, 1213 | X86_MN_VPSHLQ, 1214 | X86_MN_VPSHAB, 1215 | X86_MN_VPSHAW, 1216 | X86_MN_VPSHAD, 1217 | X86_MN_VPSHAQ, 1218 | X86_MN_LWPINS, 1219 | X86_MN_LWPVAL, 1220 | /* 3DNow */ 1221 | X86_MN_PFCMPGE, 1222 | X86_MN_PI2FW, 1223 | X86_MN_PI2FD, 1224 | X86_MN_PF2IW, 1225 | X86_MN_PF2ID, 1226 | X86_MN_PFNACC, 1227 | X86_MN_PFPNACC, 1228 | X86_MN_PFMIN, 1229 | X86_MN_PFRCP, 1230 | X86_MN_PFRSQRT, 1231 | X86_MN_PFSUB, 1232 | X86_MN_PFADD, 1233 | X86_MN_PFCMPGT, 1234 | X86_MN_PFMAX, 1235 | X86_MN_PFRCPIT1, 1236 | X86_MN_PFRSQIT1, 1237 | X86_MN_PFSUBR, 1238 | X86_MN_PFACC, 1239 | X86_MN_PFCMPEQ, 1240 | X86_MN_PFMUL, 1241 | X86_MN_PMULHRW, 1242 | X86_MN_PSWAPD, 1243 | X86_MN_PAVGUSB, 1244 | X86_MN_FFREEP, 1245 | X86_MN_FXCH4, 1246 | X86_MN_FSTDW, 1247 | X86_MN_FSTSG, 1248 | X86_MN_FXCH7, 1249 | /* FMA4 */ 1250 | X86_MN_FMADDSUBPS, 1251 | X86_MN_FMADDSUBPD, 1252 | X86_MN_FMSUBADDPS, 1253 | X86_MN_FMSUBADDPD, 1254 | X86_MN_FMADDPS, 1255 | X86_MN_FMADDSS, 1256 | X86_MN_FMADDSD, 1257 | X86_MN_FMSUBPS, 1258 | X86_MN_FMSUBPD, 1259 | X86_MN_FMSUBSS, 1260 | X86_MN_FMSUBSD, 1261 | X86_MN_FNMADDPS, 1262 | X86_MN_FNMADDPD, 1263 | X86_MN_FNMADDSS, 1264 | X86_MN_FNMADDSD, 1265 | X86_MN_FNMSUBPS, 1266 | X86_MN_FNMSUBPD, 1267 | X86_MN_FNMSUBSS, 1268 | X86_MN_FNMSUBSD, 1269 | /* TSX */ 1270 | X86_MN_XBEGIN, 1271 | X86_MN_XABORT, 1272 | /* CET */ 1273 | X86_MN_WRUSSD, 1274 | X86_MN_WRUSSQ, 1275 | X86_MN_WRSSD, 1276 | X86_MN_WRSSQ, 1277 | X86_MN_INCSSPD, 1278 | X86_MN_INCSSPQ, 1279 | X86_MN_SAVEPREVSSP, 1280 | X86_MN_RSTORSSP, 1281 | X86_MN_CLRSSBSY, 1282 | X86_MN_SETSSBSY, 1283 | 1284 | X86_MN_ANY 1285 | }; 1286 | 1287 | /***************************************************************************/ 1288 | 1289 | enum 1290 | { 1291 | X86_FLAG_NA = 0, /* flag not affected */ 1292 | X86_FLAG_T, /* flag tested */ 1293 | X86_FLAG_M, /* flag modified */ 1294 | X86_FLAG_TM, /* flag tested and modified */ 1295 | X86_FLAG_CLR, /* flag cleared */ 1296 | X86_FLAG_SET /* flag set */ 1297 | }; 1298 | 1299 | enum 1300 | { 1301 | /* dasm mode */ 1302 | X86_DMODE_16BIT = 0, /* real mode / virtual 8086 mode (16-bit) */ 1303 | X86_DMODE_32BIT, /* protected mode / long compatibility mode (32-bit) */ 1304 | X86_DMODE_64BIT, /* long mode (64-bit) */ 1305 | 1306 | /* operand size */ 1307 | X86_OSIZE_16BIT = 0, 1308 | X86_OSIZE_32BIT, 1309 | X86_OSIZE_64BIT, 1310 | 1311 | /* addressing size */ 1312 | X86_ASIZE_16BIT = 0, 1313 | X86_ASIZE_32BIT, 1314 | X86_ASIZE_64BIT, 1315 | 1316 | /* operand type */ 1317 | X86_OPTYPE_NONE = 0, /* operand invalid */ 1318 | X86_OPTYPE_REG, /* register */ 1319 | X86_OPTYPE_IMM, /* immediate */ 1320 | X86_OPTYPE_MEXPR, /* memory expression: base+index*scale+disp */ 1321 | X86_OPTYPE_MOFFS, /* memory offset: A0-A3 */ 1322 | X86_OPTYPE_ABS, /* absolute address: jmp far seg:offset */ 1323 | X86_OPTYPE_REL, /* relative to rIP */ 1324 | 1325 | /* operand size (effective) */ 1326 | X86_OPSIZE_NONE = 0, 1327 | X86_OPSIZE_BYTE, /* 1 bytes (8 bit) */ 1328 | X86_OPSIZE_WORD, /* 2 bytes (16 bit) */ 1329 | X86_OPSIZE_DWORD, /* 4 bytes (32 bit) */ 1330 | X86_OPSIZE_FWORD, /* 6 bytes (48 bit) */ 1331 | X86_OPSIZE_QWORD, /* 8 bytes (64 bit) */ 1332 | X86_OPSIZE_TWORD, /* 10 bytes (80 bit) */ 1333 | X86_OPSIZE_OWORD, /* 16 bytes (128 bit) */ 1334 | X86_OPSIZE_YWORD, /* 32 bytes (256 bit) */ 1335 | X86_OPSIZE_ZWORD, /* 64 bytes (512 bit) */ 1336 | 1337 | /* addressing size */ 1338 | X86_ASIZE_NONE = 0, 1339 | X86_ASIZE_WORD, /* 2 bytes (16 bit) */ 1340 | X86_ASIZE_DWORD, /* 4 bytes (32 bit) */ 1341 | X86_ASIZE_QWORD, /* 8 bytes (64 bit) */ 1342 | 1343 | /* displacement size */ 1344 | X86_DISP_NONE = 0, /* no displacement */ 1345 | X86_DISP_8, /* byte displacement */ 1346 | X86_DISP_16, /* word displacement */ 1347 | X86_DISP_32 /* dword displacement */ 1348 | }; 1349 | 1350 | typedef union 1351 | { 1352 | uint8_t u8; 1353 | uint16_t u16; 1354 | uint32_t u32; 1355 | uint64_t u64; 1356 | int8_t s8; 1357 | int16_t s16; 1358 | int32_t s32; 1359 | int64_t s64; 1360 | 1361 | } data_type; 1362 | 1363 | typedef data_type x86_reg; 1364 | 1365 | typedef struct 1366 | { 1367 | 1368 | #if !defined(X86_DASM_NOFMT) || defined(X86_DASM_DEBUG) 1369 | 1370 | char str[64]; 1371 | 1372 | #endif 1373 | 1374 | uint8_t type; /* X86_OPTYPE_ */ 1375 | uint8_t size; /* X86_OPSIZE_ */ 1376 | uint8_t size_orig; /* X86_OPSIZE_, orig. before fixes/sign-extension */ 1377 | uint8_t asize; /* X86_ASIZE_ */ 1378 | uint8_t seg; /* X86_REG_ES/DS/SS/FS/GS/CS */ 1379 | uint8_t pos; /* position of IMM/REL/MOFFS/DISP in buffer */ 1380 | 1381 | union 1382 | { 1383 | /* X86_OPTYPE_ABS */ 1384 | struct 1385 | { 1386 | uint16_t seg; 1387 | data_type offs; 1388 | 1389 | } abs; 1390 | 1391 | /* X86_OPTYPE_REG */ 1392 | uint8_t reg; /* X86_REG_ */ 1393 | 1394 | /* X86_OPTYPE_MEXPR */ 1395 | struct 1396 | { 1397 | uint8_t scale; /* 1, 2, 4, 8 */ 1398 | uint8_t index; /* X86_REG_ */ 1399 | uint8_t base; /* X86_REG_ */ 1400 | uint8_t disp_size; /* X86_DISP_ */ 1401 | data_type disp; 1402 | 1403 | } mexpr; 1404 | 1405 | /* X86_OPTYPE_IMM */ 1406 | /* X86_OPTYPE_MOFFS */ 1407 | /* X86_OPTYPE_REL */ 1408 | data_type data; 1409 | }; 1410 | 1411 | } x86_operand_t; 1412 | 1413 | typedef struct 1414 | { 1415 | uint8_t buffer[32]; /* buffer to disasm */ 1416 | 1417 | #if !defined(X86_DASM_NOFMT) || defined(X86_DASM_DEBUG) 1418 | 1419 | char inst_str[128]; /* full formatted instruction */ 1420 | char mnem_str[32]; /* mnemonic string */ 1421 | 1422 | #endif 1423 | 1424 | union 1425 | { 1426 | uint8_t pos; /* position in buffer (cursor) */ 1427 | uint8_t len; /* instruction lenght */ 1428 | }; 1429 | 1430 | uint8_t dmode; /* X86_DMODE_ */ 1431 | uint8_t osize; /* X86_OSIZE_ */ 1432 | uint8_t asize; /* X86_ASIZE_ */ 1433 | uint8_t iset; /* X86_ISET_ */ 1434 | uint16_t mnem; /* X86_MN_ */ 1435 | 1436 | uint8_t modrm; 1437 | uint8_t sib; 1438 | uint8_t vsib_base; 1439 | 1440 | /* prefixes */ 1441 | uint8_t pfx_rex; 1442 | uint8_t pfx_last; 1443 | uint8_t pfx_seg; 1444 | uint8_t pfx_mandatory; 1445 | 1446 | union 1447 | { 1448 | uint8_t pfx_vex[3]; 1449 | uint8_t pfx_xop[3]; 1450 | }; 1451 | 1452 | /* positions in buffer */ 1453 | uint8_t pos_modrm : 4; 1454 | uint8_t pos_sib : 4; 1455 | uint8_t pos_rex : 4; 1456 | uint8_t pos_opcode : 4; 1457 | 1458 | /* count of operand-size ovverride prefixes */ 1459 | uint8_t pfx_c_osize : 4; 1460 | 1461 | /* prefixes present */ 1462 | uint8_t pfx_p_rex : 1; 1463 | uint8_t pfx_p_seg : 1; 1464 | uint8_t pfx_p_osize : 1; 1465 | uint8_t pfx_p_asize : 1; 1466 | uint8_t pfx_p_lock : 1; 1467 | uint8_t pfx_p_rep : 1; 1468 | uint8_t pfx_p_repne : 1; 1469 | uint8_t pfx_p_vex2b : 1; 1470 | uint8_t pfx_p_vex3b : 1; 1471 | uint8_t pfx_p_evex : 1; 1472 | uint8_t pfx_p_xop : 1; 1473 | 1474 | /* bytes present */ 1475 | uint8_t p_modrm : 1; 1476 | uint8_t p_sib : 1; 1477 | uint8_t p_vsib : 1; 1478 | 1479 | /* current table link */ 1480 | const x86_table_link_t* table_link; 1481 | 1482 | /* operands */ 1483 | x86_operand_t operands[4]; 1484 | 1485 | /* EFLAGS */ 1486 | x86_eflags_t eflags; 1487 | 1488 | /* current instruction pointer */ 1489 | x86_reg rip; 1490 | 1491 | /* destination instruction pointer (for relative inst.) */ 1492 | x86_reg dest_rip; 1493 | 1494 | } x86_dasm_context_t; 1495 | 1496 | typedef struct 1497 | { 1498 | x86_reg rax; 1499 | x86_reg rcx; 1500 | x86_reg rdx; 1501 | x86_reg rbx; 1502 | x86_reg rsp; 1503 | x86_reg rbp; 1504 | x86_reg rsi; 1505 | x86_reg rdi; 1506 | 1507 | /* 64-bit mode only */ 1508 | x86_reg r8; 1509 | x86_reg r9; 1510 | x86_reg r10; 1511 | x86_reg r11; 1512 | x86_reg r12; 1513 | x86_reg r13; 1514 | x86_reg r14; 1515 | x86_reg r15; 1516 | 1517 | x86_reg rip; 1518 | 1519 | /* base address of the segments, -- not the segment selector! -- */ 1520 | x86_reg es; 1521 | x86_reg cs; 1522 | x86_reg ss; 1523 | x86_reg ds; 1524 | x86_reg fs; 1525 | x86_reg gs; 1526 | 1527 | } x86_regs_t; 1528 | 1529 | /* utility functions */ 1530 | void x86_set_buffer(x86_dasm_context_t* x86_dctx, void* code); 1531 | 1532 | void x86_set_ip(x86_dasm_context_t* x86_dctx, uint64_t ip); 1533 | 1534 | void x86_set_dmode(x86_dasm_context_t* x86_dctx, int dmode); 1535 | 1536 | bool_t x86_is_jmp(x86_dasm_context_t* x86_dctx); 1537 | 1538 | bool_t x86_is_jmpcc(x86_dasm_context_t* x86_dctx); 1539 | 1540 | bool_t x86_is_ret(x86_dasm_context_t* x86_dctx); 1541 | 1542 | bool_t x86_resolve_rip(x86_dasm_context_t* x86_dctx, ulong_t i, uint64_t* addr); 1543 | 1544 | uint64_t x86_resolve_op(x86_dasm_context_t* x86_dctx, x86_regs_t* regs, ulong_t i); 1545 | 1546 | /* disassembling function */ 1547 | int x86_dasm(x86_dasm_context_t* x86_dctx); 1548 | 1549 | #ifdef __cplusplus 1550 | } 1551 | #endif 1552 | 1553 | #endif //_DASM_H_ -------------------------------------------------------------------------------- /include/x86_dasm_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of x86_dasm. 4 | 5 | x86_dasm is a compact x86-64 disassembling library 6 | 7 | Copyright 2021 / the`janitor / < email: base64dec(dGhlLmphbml0b3JAcHJvdG9ubWFpbC5jb20=) > 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | */ 22 | #ifndef _DASM_MACROS_H_ 23 | #define _DASM_MACROS_H_ 24 | 25 | #include "x86_dasm.h" 26 | 27 | /* 28 | This file provides some helper macros in an attempt to simplify conditional expressions. 29 | 30 | The core macros are part of the P99 macro suite for C99 by Jens Gustedt, with some slight modifications. 31 | - https://gitlab.inria.fr/gustedt/p99 32 | 33 | */ 34 | 35 | /*********************************************************************************************************************** 36 | 37 | Core 38 | 39 | ***********************************************************************************************************************/ 40 | 41 | #define EXPAND(x) x 42 | 43 | #define PP_CONCAT_(v1, v2) v1 ## v2 44 | #define PP_CONCAT(v1, v2) PP_CONCAT_(v1, v2) 45 | 46 | #define PP_CONCAT5_(_0, _1, _2, _3, _4) _0 ## _1 ## _2 ## _3 ## _4 47 | 48 | #define PP_IDENTITY_(x) x 49 | #define PP_IDENTITY(x) PP_IDENTITY_(x) 50 | 51 | #define PP_VA_ARGS_(...) __VA_ARGS__ 52 | #define PP_VA_ARGS(...) PP_VA_ARGS_(__VA_ARGS__) 53 | 54 | #define PP_IDENTITY_VA_ARGS_(x, ...) x, __VA_ARGS__ 55 | #define PP_IDENTITY_VA_ARGS(x, ...) PP_IDENTITY_VA_ARGS_(x, __VA_ARGS__) 56 | 57 | #define PP_IIF_0(x, ...) __VA_ARGS__ 58 | #define PP_IIF_1(x, ...) x 59 | #define PP_IIF(c) PP_CONCAT_(PP_IIF_, c) 60 | 61 | #define PP_HAS_COMMA(...) \ 62 | PP_IDENTITY(PP_VA_ARGS_TAIL(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)) 63 | 64 | #define PP_IS_EMPTY_TRIGGER_PARENTHESIS_(...) , 65 | 66 | #define PP_IS_EMPTY(...) PP_IS_EMPTY_( \ 67 | /* test if there is just one argument, eventually an empty one */ \ 68 | PP_HAS_COMMA(__VA_ARGS__), \ 69 | /* test if _TRIGGER_PARENTHESIS_ together with the argument adds a comma */ \ 70 | PP_HAS_COMMA(PP_IS_EMPTY_TRIGGER_PARENTHESIS_ __VA_ARGS__), \ 71 | /* test if the argument together with a parenthesis adds a comma */ \ 72 | PP_HAS_COMMA(__VA_ARGS__ ()), \ 73 | /* test if placing it between _TRIGGER_PARENTHESIS_ and the parenthesis adds a comma */ \ 74 | PP_HAS_COMMA(PP_IS_EMPTY_TRIGGER_PARENTHESIS_ __VA_ARGS__ ())) 75 | 76 | #define PP_IS_EMPTY_(_0, _1, _2, _3) PP_HAS_COMMA(PP_CONCAT5_(PP_IS_EMPTY_IS_EMPTY_CASE_, _0, _1, _2, _3)) 77 | #define PP_IS_EMPTY_IS_EMPTY_CASE_0001 , 78 | 79 | #define PP_VA_ARGS_SIZE(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(0, PP_VA_ARGS_SIZE_(__VA_ARGS__, PP_VA_ARGS_SEQ64())) 80 | #define PP_VA_ARGS_SIZE_(...) PP_IDENTITY(PP_VA_ARGS_TAIL(__VA_ARGS__)) 81 | 82 | #define PP_VA_ARGS_TAIL(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,_17,_18,_19,_20,_21,_22, x, ...) x 83 | #define PP_VA_ARGS_SEQ64() 23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 84 | 85 | /*********************************************************************************************************************** 86 | 87 | Register Operand 88 | 89 | Examples: REG(), REG32(), REG(RAX), REG(R8L) 90 | 91 | ***********************************************************************************************************************/ 92 | 93 | #define REG_CHECK_TYPE() type == X86_OPTYPE_REG 94 | #define REG_CHECK_SIZE(_1) size == X86_OPSIZE_##_1 95 | #define REG_0() REG_CHECK_TYPE(), REG_CHECK_TYPE(), REG_CHECK_TYPE() 96 | #define REG_1(_1) reg == REG_##_1, REG_CHECK_TYPE(), REG_CHECK_TYPE() 97 | #define REG_(N) REG_##N 98 | #define REG_EVAL(N) REG_(N) 99 | #define REG_INTERNAL(...) EXPAND(REG_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) 100 | 101 | #define REG(...) REG_INTERNAL(__VA_ARGS__) , REG_CHECK_TYPE() , REG_CHECK_TYPE() 102 | #define REG8(...) REG_INTERNAL(__VA_ARGS__) , REG_CHECK_SIZE(BYTE) , REG_CHECK_TYPE() 103 | #define REG16(...) REG_INTERNAL(__VA_ARGS__) , REG_CHECK_SIZE(WORD) , REG_CHECK_TYPE() 104 | #define REG32(...) REG_INTERNAL(__VA_ARGS__) , REG_CHECK_SIZE(DWORD) , REG_CHECK_TYPE() 105 | #define REG64(...) REG_INTERNAL(__VA_ARGS__) , REG_CHECK_SIZE(QWORD) , REG_CHECK_TYPE() 106 | 107 | /*********************************************************************************************************************** 108 | 109 | Immediate Operand 110 | 111 | Examples: IMM(), IMM8(), IMMS16(-2), IMM32(0xFFFFFFF8) 112 | 113 | ***********************************************************************************************************************/ 114 | 115 | #define IMM_CHECK_TYPE() type == X86_OPTYPE_IMM 116 | #define IMM_CHECK_SIZE(_1) size == X86_OPSIZE_##_1 117 | #define IMM_0() IMM_CHECK_TYPE() 118 | #define IMM_1(_1) data.u64 == (uint64_t)_1 119 | #define IMM_2(_1, _2) data.##_1 == _2 120 | #define IMM_(N) IMM_##N 121 | #define IMM_EVAL(N) IMM_(N) 122 | #define IMM_INTERNAL(...) EXPAND(IMM_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) , \ 123 | IMM_CHECK_TYPE() , IMM_CHECK_TYPE() , IMM_CHECK_TYPE() 124 | 125 | #define IMM(...) IMM_INTERNAL(__VA_ARGS__) , IMM_CHECK_TYPE() 126 | 127 | #define IMMU8(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(u8, __VA_ARGS__)) , \ 128 | IMM_CHECK_SIZE(BYTE) 129 | 130 | #define IMMU16(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(u16, __VA_ARGS__)) , \ 131 | IMM_CHECK_SIZE(WORD) 132 | 133 | #define IMMU32(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(u32, __VA_ARGS__)) , \ 134 | IMM_CHECK_SIZE(DWORD) 135 | 136 | #define IMMU64(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(u64, __VA_ARGS__)) , \ 137 | IMM_CHECK_SIZE(QWORD) 138 | 139 | #define IMMS8(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(s8, __VA_ARGS__)) , \ 140 | IMM_CHECK_SIZE(BYTE) 141 | 142 | #define IMMS16(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(s16, __VA_ARGS__)) , \ 143 | IMM_CHECK_SIZE(WORD) 144 | 145 | #define IMMS32(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(s32, __VA_ARGS__)) , \ 146 | IMM_CHECK_SIZE(DWORD) 147 | 148 | #define IMMS64(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(IMM_INTERNAL(__VA_ARGS__), IMM_INTERNAL(s64, __VA_ARGS__)) , \ 149 | IMM_CHECK_SIZE(QWORD) 150 | 151 | #define IMM8(...) IMMU8(__VA_ARGS__) 152 | #define IMM16(...) IMMU16(__VA_ARGS__) 153 | #define IMM32(...) IMMU32(__VA_ARGS__) 154 | #define IMM64(...) IMMU64(__VA_ARGS__) 155 | 156 | /*********************************************************************************************************************** 157 | 158 | Memory Offset Operand 159 | 160 | Examples: MOFFS32(), MOFFS(0xFF800000) 161 | 162 | ***********************************************************************************************************************/ 163 | 164 | #define MOFFS_CHECK_TYPE() type == X86_OPTYPE_MOFFS 165 | #define MOFFS_CHECK_SIZE(_1) size == X86_OPSIZE_##_1 166 | #define MOFFS_0() MOFFS_CHECK_TYPE() 167 | #define MOFFS_1(_1) data.u64 == (uint64_t)_1 168 | #define MOFFS_2(_1, _2) data.##_1 == _2 169 | #define MOFFS_(N) MOFFS_##N 170 | #define MOFFS_EVAL(N) MOFFS_(N) 171 | #define MOFFS_INTERNAL(...) EXPAND(MOFFS_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) , \ 172 | MOFFS_CHECK_TYPE() , MOFFS_CHECK_TYPE() , MOFFS_CHECK_TYPE() 173 | 174 | #define MOFFS(...) MOFFS_INTERNAL(__VA_ARGS__) , MOFFS_CHECK_TYPE() 175 | 176 | #define MOFFS16(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(MOFFS_INTERNAL(__VA_ARGS__), MOFFS_INTERNAL(u16, __VA_ARGS__)) , \ 177 | MOFFS_CHECK_SIZE(WORD) 178 | 179 | #define MOFFS32(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(MOFFS_INTERNAL(__VA_ARGS__), MOFFS_INTERNAL(u32, __VA_ARGS__)) , \ 180 | MOFFS_CHECK_SIZE(DWORD) 181 | 182 | #define MOFFS64(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(MOFFS_INTERNAL(__VA_ARGS__), MOFFS_INTERNAL(u64, __VA_ARGS__)) , \ 183 | MOFFS_CHECK_SIZE(QWORD) 184 | 185 | /*********************************************************************************************************************** 186 | 187 | Absolute Address Operand 188 | 189 | Examples: ABS32(0x33, 0x77546009), ABS64() 190 | 191 | ***********************************************************************************************************************/ 192 | 193 | #define ABS_CHECK_TYPE() type == X86_OPTYPE_ABS 194 | #define ABS_CHECK_SIZE(_1) size == X86_OPSIZE_##_1 195 | #define ABS_0() ABS_CHECK_TYPE(), ABS_CHECK_TYPE() 196 | #define ABS_1(_1) abs.seg == _1, ABS_CHECK_TYPE() 197 | #define ABS_3(_1, _2, _3) abs.seg == _2, abs.offs.##_1 == _3 198 | #define ABS_(N) ABS_##N 199 | #define ABS_EVAL(N) ABS_(N) 200 | #define ABS_INTERNAL(...) EXPAND(ABS_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) , \ 201 | ABS_CHECK_TYPE() , ABS_CHECK_TYPE() 202 | 203 | #define ABS(...) ABS_INTERNAL(__VA_ARGS__) , ABS_CHECK_TYPE() 204 | 205 | #define ABS16(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(ABS_INTERNAL(__VA_ARGS__), ABS_INTERNAL(u16, __VA_ARGS__)) , \ 206 | ABS_CHECK_SIZE(DWORD) 207 | 208 | #define ABS32(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(ABS_INTERNAL(__VA_ARGS__), ABS_INTERNAL(u32, __VA_ARGS__)) , \ 209 | ABS_CHECK_SIZE(FWORD) 210 | 211 | #define ABS64(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(ABS_INTERNAL(__VA_ARGS__), ABS_INTERNAL(u64, __VA_ARGS__)) , \ 212 | ABS_CHECK_SIZE(TWORD) 213 | 214 | /*********************************************************************************************************************** 215 | 216 | Relative Operand 217 | 218 | Examples: REL8(), REL(-2), RELDST(0xBADF00D) 219 | 220 | ***********************************************************************************************************************/ 221 | 222 | #define REL_CHECK_TYPE() type == X86_OPTYPE_REL 223 | #define REL_CHECK_SIZE(_1) size == X86_OPSIZE_##_1 224 | #define REL_0() REL_CHECK_TYPE() 225 | #define REL_1(_1) data.u64 == (uint64_t)_1 226 | #define REL_2(_1, _2) data.##_1 == _2 227 | #define REL_(N) REL_##N 228 | #define REL_EVAL(N) REL_(N) 229 | #define REL_INTERNAL(...) EXPAND(REL_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) , \ 230 | REL_CHECK_TYPE() , REL_CHECK_TYPE() , REL_CHECK_TYPE() 231 | 232 | #define REL(...) REL_INTERNAL(__VA_ARGS__) , REL_CHECK_TYPE() 233 | 234 | #define REL8(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(REL_INTERNAL(__VA_ARGS__), REL_INTERNAL(s8, __VA_ARGS__)) , \ 235 | REL_CHECK_SIZE(BYTE) 236 | 237 | #define REL16(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(REL_INTERNAL(__VA_ARGS__), REL_INTERNAL(s16, __VA_ARGS__)) , \ 238 | REL_CHECK_SIZE(WORD) 239 | 240 | #define REL32(...) PP_IIF(PP_IS_EMPTY(__VA_ARGS__))(REL_INTERNAL(__VA_ARGS__), REL_INTERNAL(s32, __VA_ARGS__)) , \ 241 | REL_CHECK_SIZE(DWORD) 242 | 243 | #define RELDST(_1) dest_rip.u64 == (uint64_t)_1 244 | 245 | /*********************************************************************************************************************** 246 | 247 | Memory Expression Operand 248 | 249 | Examples: MEXPR(EAX), MEXPR(RAX, RCX, 2, 0x1BADB002) 250 | 251 | ***********************************************************************************************************************/ 252 | 253 | #define MEXPR_CHECK_TYPE() type == X86_OPTYPE_MEXPR 254 | 255 | #define MEXPR_0() \ 256 | MEXPR_CHECK_TYPE(), \ 257 | MEXPR_CHECK_TYPE(), \ 258 | MEXPR_CHECK_TYPE(), \ 259 | MEXPR_CHECK_TYPE(), \ 260 | MEXPR_CHECK_TYPE() 261 | 262 | #define MEXPR_1(_1) \ 263 | mexpr.base == X86_REG_##_1, \ 264 | MEXPR_CHECK_TYPE(), \ 265 | MEXPR_CHECK_TYPE(), \ 266 | MEXPR_CHECK_TYPE(), \ 267 | MEXPR_CHECK_TYPE() 268 | 269 | #define MEXPR_2(_1, _2) \ 270 | mexpr.base == X86_REG_##_1, \ 271 | mexpr.index == X86_REG_##_2, \ 272 | MEXPR_CHECK_TYPE(), \ 273 | MEXPR_CHECK_TYPE(), \ 274 | MEXPR_CHECK_TYPE() 275 | 276 | #define MEXPR_3(_1, _2, _3) \ 277 | mexpr.base == X86_REG_##_1, \ 278 | mexpr.index == X86_REG_##_2, \ 279 | mexpr.scale == _3, \ 280 | MEXPR_CHECK_TYPE(), \ 281 | MEXPR_CHECK_TYPE() 282 | 283 | #define MEXPR_4(_1, _2, _3, _4) \ 284 | mexpr.base == X86_REG_##_1, \ 285 | mexpr.index == X86_REG_##_2, \ 286 | mexpr.scale == _3, \ 287 | mexpr.disp.u64 == (uint64_t)_4, \ 288 | MEXPR_CHECK_TYPE() 289 | 290 | #define MEXPR_(N) MEXPR_##N 291 | #define MEXPR_EVAL(N) MEXPR_(N) 292 | #define MEXPR(...) EXPAND(MEXPR_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) 293 | 294 | /*********************************************************************************************************************** 295 | 296 | Matching Functions 297 | 298 | Examples: 299 | 300 | X86M(&ctx, ANY, REG(), REG()) 301 | X86M(&ctx, MOV, REG8(), IMM8()) 302 | X86M(&ctx, CALL, RELDST(0xD00D2BAD)) 303 | X86M(&ctx, JMP, REL(-2)) 304 | 305 | ***********************************************************************************************************************/ 306 | 307 | #define OP_MATCH(_1, _2, _3, _4, _5, _6, _7) \ 308 | ((_1)->operands[_2]._3 && (_1)->operands[_2]._4 && \ 309 | (_1)->operands[_2]._5 && (_1)->operands[_2]._6 && \ 310 | (_1)->operands[_2]._7) 311 | 312 | #define INST_MATCH_0() , 313 | #define INST_MATCH_1(_1) , 314 | #define INST_MATCH_2(_1, _2) ((_1)->mnem == X86_MN_##_2 || X86_MN_##_2 == X86_MN_ANY) 315 | #define INST_MATCH_3(_1, _2, _3) (IMATCH_2(_1, _2) && ((_1)->_3)) 316 | 317 | #define INST_MATCH_7(_1, _2, _3, _4, _5, _6, _7) \ 318 | (INST_MATCH_2(_1, _2) && \ 319 | OP_MATCH(_1, 0, _3, _4, _5, _6, _7)) 320 | 321 | #define INST_MATCH_12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ 322 | (INST_MATCH_7(_1, _2, _3, _4, _5, _6, _7) && \ 323 | OP_MATCH(_1, 1, _8, _9, _10, _11, _12)) 324 | 325 | #define INST_MATCH_17(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ 326 | (INST_MATCH_12(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) && \ 327 | OP_MATCH(_1, 2, _13, _14, _15, _16, _17)) 328 | 329 | #define INST_MATCH_22(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22) \ 330 | (INST_MATCH_17(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) && \ 331 | OP_MATCH(_1, 3, _18, _19, _20, _21, _22)) 332 | 333 | #define INST_MATCH_(N) INST_MATCH_##N 334 | #define INST_MATCH_EVAL(N) INST_MATCH_(N) 335 | 336 | #define X86M(...) EXPAND(INST_MATCH_EVAL(EXPAND(PP_VA_ARGS_SIZE(__VA_ARGS__)))(__VA_ARGS__)) 337 | 338 | #endif //_DASM_MACROS_H_ -------------------------------------------------------------------------------- /include/x86_dasm_tables.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of x86_dasm. 4 | 5 | x86_dasm is a compact x86-64 disassembling library 6 | 7 | Copyright 2014 / the`janitor / < email: base64dec(dGhlLmphbml0b3JAcHJvdG9ubWFpbC5jb20=) > 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | */ 22 | #ifndef _DASM_TABLES_H_ 23 | #define _DASM_TABLES_H_ 24 | 25 | #include "types.h" 26 | 27 | /* 28 | #define X86_DASM_DEBUG : enable debug output 29 | #define X86_DASM_NOFMT : disable all formatting/strings 30 | #define X86_DASM_NLE : if not on a little-endian system 31 | */ 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /**************************************************************************** 38 | 39 | Instruction format 40 | 41 | ****************************************************************************/ 42 | 43 | /* 44 | the total number of bytes in an instruction encoding must be less than 45 | or equal to 15 46 | */ 47 | #define MAX_INST_LENGTH 15 48 | 49 | #define ESCAPE_OPCODE_2B 0x0f 50 | #define ESCAPE_OPCODE_3B_1 0x38 51 | #define ESCAPE_OPCODE_3B_2 0x3a 52 | 53 | /* 54 | MODRM byte 55 | 56 | bits 0-2: rm (rex.b, vex.b, xop.b extend this field to 4 bits) 57 | bits 3-5: reg (rex.r, vex.r, xop.r extend this field to 4 bits) 58 | bits 6-7: mod 59 | */ 60 | #define MODRM_RM(b) ((b >> 0) & 7) 61 | #define MODRM_REG(b) ((b >> 3) & 7) 62 | #define MODRM_MOD(b) ((b >> 6) & 3) 63 | 64 | /* 65 | SIB byte 66 | 67 | bits 0-2: base (rex.b extends this field to 4 bits) 68 | bits 3-5: index (rex.x extends this field to 4 bits) 69 | bits 6-7: scale (00 = 1, 01 = 2, 10 = 4, 11 = 8) 70 | 71 | effective_address = scale * index + base + disp8/16/32 72 | */ 73 | #define SIB_BASE(b) ((b >> 0) & 7) 74 | #define SIB_INDEX(b) ((b >> 3) & 7) 75 | #define SIB_SCALE(b) ((b >> 6) & 3) 76 | 77 | /* 78 | REX byte 79 | 80 | bit 0: b (msb extension of modrm.rm or sib.base or opcode reg field) 81 | bit 1: x (msb extension of sib.index) 82 | bit 2: r (msb extension of modrm.reg) 83 | bit 3: w (0 = default operand size, 1 = 64-bit operand size) 84 | */ 85 | #define REX_PREFIX(b) (((b >> 4) & 0x0f) == 4) 86 | #define _REX_B(b) ((b >> 0) & 1) 87 | #define _REX_X(b) ((b >> 1) & 1) 88 | #define _REX_R(b) ((b >> 2) & 1) 89 | #define _REX_W(b) ((b >> 3) & 1) 90 | 91 | /* 92 | VEX 2-byte 93 | */ 94 | #define _VEX_2B_PP(b) ((b >> 0) & 3) 95 | #define _VEX_2B_L(b) ((b >> 2) & 1) 96 | #define _VEX_2B_VVVV(b) ((~(b >> 3)) & 0x0f) 97 | #define _VEX_2B_R(b) ((~(b >> 7)) & 1) 98 | 99 | #define VEX_2B_PM(b) (MODRM_MOD(b) == 3) /* LDS must have modrm.mod = !11b */ 100 | 101 | /* 102 | VEX 3-byte 103 | */ 104 | #define _VEX_3B_MMMMM(b) ((b >> 0) & 0x1f) 105 | #define _VEX_3B_B(b) ((~(b >> 5)) & 1) 106 | #define _VEX_3B_X(b) ((~(b >> 6)) & 1) 107 | #define _VEX_3B_R(b) ((~(b >> 7)) & 1) 108 | 109 | #define _VEX_3B_PP(b) ((b >> 0) & 3) 110 | #define _VEX_3B_L(b) ((b >> 2) & 1) 111 | #define _VEX_3B_VVVV(b) ((~(b >> 3)) & 0x0f) 112 | #define _VEX_3B_W(b) ((b >> 7) & 1) 113 | 114 | #define VEX_3B_PM(b) (MODRM_MOD(b) == 3) /* LES must have modrm.mod = !11b */ 115 | 116 | /* 117 | XOP 118 | */ 119 | #define _XOP_MMMMM(b) ((b >> 0) & 0x1f) 120 | #define _XOP_B(b) ((~(b >> 5)) & 1) 121 | #define _XOP_X(b) ((~(b >> 6)) & 1) 122 | #define _XOP_R(b) ((~(b >> 7)) & 1) 123 | 124 | #define _XOP_PP(b) ((b >> 0) & 3) 125 | #define _XOP_L(b) ((b >> 2) & 1) 126 | #define _XOP_VVVV(b) ((~(b >> 3)) & 0x0f) 127 | #define _XOP_W(b) ((b >> 7) & 1) 128 | 129 | #define XOP_PM(b) (MODRM_MOD(b) == 3) 130 | #define XOP_VALID(b) (_XOP_MMMMM(b) > 7 && _XOP_MMMMM(b) < 11) 131 | 132 | /* 133 | EVEX 134 | */ 135 | #define _EVEX_B(b) ((~(b >> 5)) & 1) 136 | #define _EVEX_X(b) ((~(b >> 6)) & 1) 137 | #define _EVEX_R(b) ((~(b >> 7)) & 1) 138 | #define _EVEX_RR(b) ((~(b >> 4)) & 1) /* R' */ 139 | #define _EVEX_MM(b) ((b >> 0) & 3) 140 | 141 | #define _EVEX_PP(b) ((b >> 0) & 3) 142 | #define _EVEX_W(b) ((b >> 7) & 1) 143 | #define _EVEX_VVVV(b) ((~(b >> 3)) & 0x0f) 144 | 145 | #define _EVEX_Z(b) ((b >> 7) & 1) 146 | #define _EVEX_LL(b) ((b >> 6) & 1) /* L' */ 147 | #define _EVEX_L(b) ((b >> 5) & 1) 148 | #define _EVEX_BB(b) ((b >> 4) & 1) 149 | #define _EVEX_VV(b) ((~(b >> 3)) & 1) /* V' */ 150 | #define _EVEX_AAA(b) ((b >> 0) & 7) 151 | 152 | #define EVEX_P0(b) (((b >> 2) & 3) == 0) /* check on P0, else #UD */ 153 | #define EVEX_P1(b) (((b >> 2) & 1) == 1) /* check on P1, else #UD */ 154 | #define EVEX_PM(b) (MODRM_MOD(b) == 3) /* BOUND must have modrm.mod = !11b */ 155 | 156 | 157 | /* 158 | prefixes 159 | */ 160 | #define PREFIX_OSIZE 0x66 /* operand-size override */ 161 | #define PREFIX_ASIZE 0x67 /* address-size override */ 162 | #define PREFIX_SEGOVRD_CS 0x2e /* segment override, ignored in 64-bit mode */ 163 | #define PREFIX_SEGOVRD_DS 0x3e /* segment override, ignored in 64-bit mode */ 164 | #define PREFIX_SEGOVRD_ES 0x26 /* segment override, ignored in 64-bit mode */ 165 | #define PREFIX_SEGOVRD_FS 0x64 /* segment override */ 166 | #define PREFIX_SEGOVRD_GS 0x65 /* segment override */ 167 | #define PREFIX_SEGOVRD_SS 0x36 /* segment override, ignored in 64-bit mode */ 168 | #define PREFIX_LOCK 0xf0 /* lock rw atomically */ 169 | #define PREFIX_REPNE 0xf2 170 | #define PREFIX_REP 0xf3 171 | #define PREFIX_BRT 0x2e /* branch taken (hint), only with jcc */ 172 | #define PREFIX_BRNT 0x3e /* branch not taken (hint), only with jcc */ 173 | #define PREFIX_VEX_3B 0xc4 174 | #define PREFIX_VEX_2B 0xc5 175 | #define PREFIX_EVEX 0x62 176 | #define PREFIX_XOP 0x8f 177 | 178 | /**************************************************************************** 179 | 180 | addressing methods 181 | 182 | Intel 64 and IA-32 Architectures Software Developer�s Manual, Volume 2 183 | Order Number: 325383-055US 184 | June 2015 185 | 186 | ****************************************************************************/ 187 | 188 | enum 189 | { 190 | AM_NONE = 0, 191 | 192 | /* 193 | direct address: the instruction has no ModR/M byte; the address of the 194 | operand is encoded in the instruction. No base register, index register, 195 | or scaling factor can be applied (for example, far JMP (EA)). 196 | */ 197 | AM_A, 198 | 199 | /* 200 | the VEX.vvvv field of the VEX prefix selects a general purpose register. 201 | */ 202 | AM_B, 203 | 204 | /* 205 | the reg field of the ModR/M byte selects a control register 206 | (for example, MOV (0F20, 0F22)). 207 | */ 208 | AM_C, 209 | 210 | /* 211 | the reg field of the ModR/M byte selects a debug register 212 | (for example, MOV (0F21, 0F23)). 213 | */ 214 | AM_D, 215 | 216 | /* 217 | a ModR/M byte follows the opcode and specifies the operand. The operand 218 | is either a general-purpose register or a memory address. If it is a 219 | memory address, the address is computed from a segment register and any 220 | of the following values: a base register, an index register, a scaling 221 | factor, a displacement. 222 | */ 223 | AM_E, 224 | 225 | /* 226 | EFLAGS/RFLAGS register 227 | */ 228 | AM_F, 229 | 230 | /* 231 | the reg field of the ModR/M byte selects a general register 232 | (for example, AX (000)). 233 | */ 234 | AM_G, 235 | 236 | /* 237 | the VEX.vvvv field of the VEX prefix selects a 128-bit XMM register or a 238 | 256-bit YMM register, determined by operand type. For legacy SSE 239 | encodings this operand does not exist, changing the instruction to 240 | destructive form. 241 | */ 242 | AM_H, 243 | 244 | /* 245 | immediate data: the operand value is encoded in subsequent bytes of the 246 | instruction. 247 | */ 248 | AM_I, 249 | 250 | /* 251 | the instruction contains a relative offset to be added to the instruction 252 | pointer register (for example, JMP (0E9), LOOP). 253 | */ 254 | AM_J, 255 | 256 | /* 257 | the upper 4 bits of the 8-bit immediate selects a 128-bit XMM register or 258 | a 256-bit YMM register, determined by operand type. 259 | (the MSB is ignored in 32-bit mode) 260 | */ 261 | AM_L, 262 | 263 | /* 264 | the ModR/M byte may refer only to memory (for example, BOUND, LES, LDS, 265 | LSS, LFS, LGS, CMPXCHG8B). 266 | */ 267 | AM_M, 268 | 269 | /* 270 | the R/M field of the ModR/M byte selects a packed-quadword, 271 | MMX technology register. 272 | */ 273 | AM_N, 274 | 275 | /* 276 | the instruction has no ModR/M byte. The offset of the operand is coded as 277 | a word or double word (depending on address size attribute) in the 278 | instruction. No base register, index register, or scaling factor can be 279 | applied (for example, MOV (A0�A3)). 280 | */ 281 | AM_O, 282 | 283 | /* 284 | the reg field of the ModR/M byte selects a packed quadword 285 | MMX technology register. 286 | */ 287 | AM_P, 288 | 289 | /* 290 | a ModR/M byte follows the opcode and specifies the operand. The operand 291 | is either an MMX technology register or a memory address. If it is a 292 | memory address, the address is computed from a segment register and any 293 | of the following values: a base register, an index register, a scaling 294 | factor, and a displacement. 295 | */ 296 | AM_Q, 297 | 298 | /* 299 | the R/M field of the ModR/M byte may refer only to a general register 300 | (for example, MOV (0F20-0F23)). 301 | */ 302 | AM_R, 303 | 304 | /* 305 | the reg field of the ModR/M byte selects a segment register 306 | (for example, MOV (8C,8E)). 307 | */ 308 | AM_S, 309 | 310 | /* 311 | the R/M field of the ModR/M byte selects a 128-bit XMM register or a 312 | 256-bit YMM register, determined by operand type. 313 | */ 314 | AM_U, 315 | 316 | /* 317 | the reg field of the ModR/M byte selects a 128-bit XMM register or a 318 | 256-bit YMM register, determined by operand type. 319 | */ 320 | AM_V, 321 | 322 | /* 323 | a ModR/M byte follows the opcode and specifies the operand. The operand 324 | is either a 128-bit XMM register, a 256-bit YMM register (determined by 325 | operand type), or a memory address. If it is a memory address, the 326 | address is computed from a segment register and any of the following 327 | values: a base register, an index register, a scaling factor, and a 328 | displacement. 329 | */ 330 | AM_W, 331 | 332 | /* 333 | memory addressed by the DS:rSI register pair (for example, MOVS, CMPS, 334 | OUTS, or LODS). 335 | */ 336 | AM_X, 337 | 338 | /* 339 | memory addressed by the ES:rDI register pair (for example, MOVS, CMPS, 340 | INS, STOS, or SCAS). 341 | */ 342 | AM_Y, 343 | 344 | /* 345 | implicit immediate data of value 1 346 | */ 347 | AM_I1, 348 | 349 | /* 350 | implicit immediate data of value 3 351 | */ 352 | AM_I3, 353 | 354 | /* 355 | register RAX/EAX/AX depending on the operand's size attribute 356 | (no REX.B extension) 357 | */ 358 | AM_rAX, 359 | AM_rCX, 360 | AM_rDX, 361 | AM_rBX, 362 | AM_rSP, 363 | AM_rBP, 364 | AM_rSI, 365 | AM_rDI, 366 | 367 | /* 368 | register RAX/EAX/AX, R8/R8D/R8W depending on the operand's size 369 | attribute (with REX.B extension) 370 | 371 | when any REX prefix is used, SPL, BPL, SIL and DIL are used. 372 | otherwise, without any REX prefix AH, CH, DH and BH are used. 373 | */ 374 | AM_rAX_r8, 375 | AM_rCX_r9, 376 | AM_rDX_r10, 377 | AM_rBX_r11, 378 | AM_rSP_r12, 379 | AM_rBP_r13, 380 | AM_rSI_r14, 381 | AM_rDI_r15, 382 | 383 | /* 384 | register ST(0), FPU/x87 extension 385 | */ 386 | AM_ST0, 387 | AM_ST1, 388 | AM_ST2, 389 | AM_ST3, 390 | AM_ST4, 391 | AM_ST5, 392 | AM_ST6, 393 | AM_ST7, 394 | 395 | /* 396 | register CS/DS/ES/... segment registers 397 | */ 398 | AM_ES, 399 | AM_CS, 400 | AM_SS, 401 | AM_DS, 402 | AM_FS, 403 | AM_GS, 404 | 405 | AM_MAX 406 | }; 407 | 408 | /**************************************************************************** 409 | 410 | operand types 411 | 412 | Intel 64 and IA-32 Architectures Software Developer�s Manual, Volume 2 413 | Order Number: 325383-055US 414 | June 2015 415 | 416 | ****************************************************************************/ 417 | 418 | enum 419 | { 420 | OT_NONE = 0, 421 | 422 | /* 423 | two one-word operands in memory or two double-word operands in memory, 424 | depending on operand-size attribute (used only by the BOUND instruction). 425 | */ 426 | OT_A, 427 | 428 | /* 429 | byte, regardless of operand-size attribute. 430 | */ 431 | OT_B, 432 | 433 | /* 434 | byte or word, depending on operand-size attribute. 435 | 436 | OT_C, 437 | */ 438 | 439 | /* 440 | doubleword, regardless of operand-size attribute. 441 | */ 442 | OT_D, 443 | 444 | /* 445 | double-quadword, regardless of operand-size attribute. 446 | */ 447 | OT_DQ, 448 | 449 | /* 450 | 32-bit, 48-bit, or 80-bit pointer, depending on operand-size attribute. 451 | */ 452 | OT_P, 453 | 454 | /* 455 | 128-bit or 256-bit packed double-precision floating-point data. 456 | */ 457 | OT_PD, 458 | 459 | /* 460 | quadword MMX technology register (for example: mm0). 461 | */ 462 | OT_PI, 463 | 464 | /* 465 | 128-bit or 256-bit packed single-precision floating-point data. 466 | */ 467 | OT_PS, 468 | 469 | /* 470 | quadword, regardless of operand-size attribute. 471 | */ 472 | OT_Q, 473 | 474 | /* 475 | quad-quadword (256-bits), regardless of operand-size attribute. 476 | */ 477 | OT_QQ, 478 | 479 | /* 480 | 6-byte or 10-byte pseudo-descriptor. 481 | */ 482 | OT_S, 483 | 484 | /* 485 | scalar element of a 128-bit double-precision floating data. 486 | */ 487 | OT_SD, 488 | 489 | /* 490 | scalar element of a 128-bit single-precision floating data. 491 | */ 492 | OT_SS, 493 | 494 | /* 495 | doubleword integer register (for example: eax). 496 | */ 497 | OT_SI, 498 | 499 | /* 500 | 10-byte data, regardless of operand-size attribute. 501 | tbyte, dt 502 | */ 503 | OT_T, 504 | 505 | /* 506 | word, doubleword or quadword (in 64-bit mode), depending on operand-size 507 | attribute. 508 | */ 509 | OT_V, 510 | 511 | /* 512 | word, regardless of operand-size attribute. 513 | */ 514 | OT_W, 515 | 516 | /* 517 | dq or qq based on the operand-size attribute. 518 | */ 519 | OT_X, 520 | 521 | /* 522 | doubleword or quadword (in 64-bit mode), depending on operand-size 523 | attribute. 524 | */ 525 | OT_Y, 526 | 527 | /* 528 | word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size. 529 | */ 530 | OT_Z, 531 | 532 | /* 533 | 64- or 128-bit depending on VEX.L 534 | */ 535 | OT_OQ, 536 | 537 | OT_MAX 538 | }; 539 | 540 | /**************************************************************************** 541 | 542 | operands 543 | 544 | ****************************************************************************/ 545 | 546 | #define O_NONE AM_NONE, OT_NONE 547 | 548 | /* 549 | general-purpose register operands 550 | */ 551 | #define O_AL AM_rAX, OT_B 552 | #define O_CL AM_rCX, OT_B 553 | #define O_AX AM_rAX, OT_W 554 | #define O_DX AM_rDX, OT_W 555 | #define O_eAX AM_rAX, OT_Z 556 | #define O_eCX AM_rCX, OT_Z 557 | #define O_eDX AM_rDX, OT_Z 558 | #define O_eBX AM_rBX, OT_Z 559 | #define O_eSP AM_rSP, OT_Z 560 | #define O_eBP AM_rBP, OT_Z 561 | #define O_eSI AM_rSI, OT_Z 562 | #define O_eDI AM_rDI, OT_Z 563 | #define O_rAX AM_rAX, OT_V 564 | #define O_rDX AM_rDX, OT_V 565 | #define O_rAX_r8 AM_rAX_r8, OT_V 566 | #define O_rCX_r9 AM_rCX_r9, OT_V 567 | #define O_rDX_r10 AM_rDX_r10, OT_V 568 | #define O_rBX_r11 AM_rBX_r11, OT_V 569 | #define O_rSP_r12 AM_rSP_r12, OT_V 570 | #define O_rBP_r13 AM_rBP_r13, OT_V 571 | #define O_rSI_r14 AM_rSI_r14, OT_V 572 | #define O_rDI_r15 AM_rDI_r15, OT_V 573 | #define O_AL_r8L AM_rAX_r8, OT_B 574 | #define O_CL_r9L AM_rCX_r9, OT_B 575 | #define O_DL_r10L AM_rDX_r10, OT_B 576 | #define O_BL_r11L AM_rBX_r11, OT_B 577 | #define O_AH_r12L AM_rSP_r12, OT_B 578 | #define O_CH_r13L AM_rBP_r13, OT_B 579 | #define O_DH_r14L AM_rSI_r14, OT_B 580 | #define O_BH_r15L AM_rDI_r15, OT_B 581 | 582 | /* 583 | segment register operands 584 | */ 585 | #define O_ES AM_ES, OT_NONE 586 | #define O_CS AM_CS, OT_NONE 587 | #define O_SS AM_SS, OT_NONE 588 | #define O_DS AM_DS, OT_NONE 589 | #define O_FS AM_FS, OT_NONE 590 | #define O_GS AM_GS, OT_NONE 591 | 592 | /* 593 | FPU register operands 594 | */ 595 | #define O_ST0 AM_ST0, OT_NONE 596 | #define O_ST1 AM_ST1, OT_NONE 597 | #define O_ST2 AM_ST2, OT_NONE 598 | #define O_ST3 AM_ST3, OT_NONE 599 | #define O_ST4 AM_ST4, OT_NONE 600 | #define O_ST5 AM_ST5, OT_NONE 601 | #define O_ST6 AM_ST6, OT_NONE 602 | #define O_ST7 AM_ST7, OT_NONE 603 | 604 | #define O_Ap AM_A, OT_P 605 | #define O_By AM_B, OT_Y 606 | #define O_Cy AM_C, OT_Y 607 | #define O_Dy AM_D, OT_Y 608 | #define O_Eb AM_E, OT_B 609 | #define O_Ed AM_E, OT_D 610 | #define O_Ep AM_E, OT_P 611 | #define O_Ev AM_E, OT_V 612 | #define O_Ew AM_E, OT_W 613 | #define O_Ey AM_E, OT_Y 614 | #define O_Fv AM_F, OT_V 615 | #define O_Gb AM_G, OT_B 616 | #define O_Gd AM_G, OT_D 617 | #define O_Gv AM_G, OT_V 618 | #define O_Gw AM_G, OT_W 619 | #define O_Gy AM_G, OT_Y 620 | #define O_Gz AM_G, OT_Z 621 | #define O_Gq AM_G, OT_Q 622 | #define O_Hdq AM_H, OT_DQ 623 | #define O_Hpd AM_H, OT_PD 624 | #define O_Hps AM_H, OT_PS 625 | #define O_Hq AM_H, OT_Q 626 | #define O_Hqq AM_H, OT_QQ 627 | #define O_Hsd AM_H, OT_SD 628 | #define O_Hss AM_H, OT_SS 629 | #define O_Hx AM_H, OT_X 630 | #define O_I1 AM_I1, OT_B 631 | #define O_I3 AM_I3, OT_B 632 | #define O_Ib AM_I, OT_B 633 | #define O_Id AM_I, OT_D 634 | #define O_Iv AM_I, OT_V 635 | #define O_Iw AM_I, OT_W 636 | #define O_Iz AM_I, OT_Z 637 | #define O_Jb AM_J, OT_B 638 | #define O_Jz AM_J, OT_Z 639 | #define O_Lx AM_L, OT_X 640 | #define O_Lss AM_L, OT_SS 641 | #define O_M AM_M, OT_NONE 642 | #define O_Ma AM_M, OT_A 643 | #define O_Mb AM_M, OT_B 644 | #define O_Md AM_M, OT_D 645 | #define O_Mdq AM_M, OT_DQ 646 | #define O_Mp AM_M, OT_P 647 | #define O_Mpd AM_M, OT_PD 648 | #define O_Mps AM_M, OT_PS 649 | #define O_Mq AM_M, OT_Q 650 | #define O_Moq AM_M, OT_OQ 651 | #define O_Ms AM_M, OT_S 652 | #define O_Mt AM_M, OT_T 653 | #define O_Mv AM_M, OT_V 654 | #define O_Mw AM_M, OT_W 655 | #define O_Mx AM_M, OT_X 656 | #define O_My AM_M, OT_Y 657 | #define O_Nq AM_N, OT_Q 658 | #define O_Ob AM_O, OT_B 659 | #define O_Ov AM_O, OT_V 660 | #define O_Ppi AM_P, OT_PI 661 | #define O_Pq AM_P, OT_Q 662 | #define O_Py AM_P, OT_Y 663 | #define O_Qd AM_Q, OT_D 664 | #define O_Qpi AM_Q, OT_PI 665 | #define O_Qq AM_Q, OT_Q 666 | #define O_Rd AM_R, OT_D 667 | #define O_Rb AM_R, OT_B 668 | #define O_Rw AM_R, OT_W 669 | #define O_Rq AM_R, OT_Q 670 | #define O_Ry AM_R, OT_Y 671 | #define O_Rdq AM_R, OT_DQ 672 | #define O_Rv AM_R, OT_V 673 | #define O_Ry AM_R, OT_Y 674 | #define O_Sw AM_S, OT_W 675 | #define O_Udq AM_U, OT_DQ 676 | #define O_Upd AM_U, OT_PD 677 | #define O_Ups AM_U, OT_PS 678 | #define O_Uq AM_U, OT_Q 679 | #define O_Ux AM_U, OT_X 680 | #define O_Uss AM_U, OT_SS 681 | #define O_Vdq AM_V, OT_DQ 682 | #define O_Vpd AM_V, OT_PD 683 | #define O_Vpi AM_V, OT_PI 684 | #define O_Vps AM_V, OT_PS 685 | #define O_Vq AM_V, OT_Q 686 | #define O_Vqq AM_V, OT_QQ 687 | #define O_Vsd AM_V, OT_SD 688 | #define O_Vss AM_V, OT_SS 689 | #define O_Vx AM_V, OT_X 690 | #define O_Vy AM_V, OT_Y 691 | #define O_Wd AM_W, OT_D 692 | #define O_Wdq AM_W, OT_DQ 693 | #define O_Wpd AM_W, OT_PD 694 | #define O_Wpi AM_W, OT_PI 695 | #define O_Wps AM_W, OT_PS 696 | #define O_Wq AM_W, OT_Q 697 | #define O_Woq AM_W, OT_OQ 698 | #define O_Wqq AM_W, OT_QQ 699 | #define O_Wsd AM_W, OT_SD 700 | #define O_Wss AM_W, OT_SS 701 | #define O_Wx AM_W, OT_X 702 | #define O_Xb AM_X, OT_B 703 | #define O_Xv AM_X, OT_V 704 | #define O_Xz AM_X, OT_Z 705 | #define O_Yb AM_Y, OT_B 706 | #define O_Yv AM_Y, OT_V 707 | #define O_Yz AM_Y, OT_Z 708 | 709 | /**************************************************************************** 710 | 711 | property flags 712 | 713 | ****************************************************************************/ 714 | 715 | enum 716 | { 717 | PF_NONE = 0, 718 | 719 | /* 720 | the instruction is invalid or not encodable in 64-bit mode. 40 through 721 | 4F (single-byte INC and DEC) are REX prefix combinations when in 64-bit 722 | mode (use FE/FF Grp 4 and 5 for INC and DEC). 723 | */ 724 | PF_I64 = (1 << 0), 725 | 726 | /* 727 | instruction is only available when in 64-bit mode. 728 | */ 729 | PF_O64 = (1 << 1), 730 | 731 | /* 732 | the operand size is forced to a 64-bit operand size when in 64-bit mode 733 | (prefixes that change operand size are ignored for this instruction in 734 | 64-bit mode). 735 | 736 | */ 737 | PF_F64 = (1 << 2), 738 | 739 | /* 740 | when in 64-bit mode, instruction defaults to 64-bit operand size and 741 | cannot encode 32-bit operand size. 742 | */ 743 | PF_D64 = (1 << 3), 744 | 745 | /* 746 | can accept a LOCK prefix. 747 | */ 748 | PF_LOCK = (1 << 4), 749 | 750 | /* 751 | can accept a REP prefix. 752 | */ 753 | PF_REP = (1 << 5), 754 | 755 | /* 756 | can accept a REP prefix. 757 | */ 758 | PF_REPE_REPNE = (1 << 6), 759 | 760 | /* 761 | can accept VEX prefix. 762 | */ 763 | PF_VEX = (1 << 7), 764 | 765 | /* 766 | can only accept a 128-bit VEX prefix. 767 | */ 768 | PF_VEX128 = (1 << 8), 769 | 770 | /* 771 | can only accept a 256-bit VEX prefix. 772 | */ 773 | PF_VEX256 = (1 << 9), 774 | 775 | /* 776 | requires VEX prefix. 777 | */ 778 | PF_OVEX = (1 << 10), 779 | 780 | /* 781 | last byte encodes a sse/vex condition code 782 | */ 783 | PF_CC = (1 << 11), 784 | 785 | /* 786 | last byte encodes a xop condition code 787 | */ 788 | PF_XOPCC = (1 << 12), 789 | 790 | /* 791 | the instruction has prefixes N/A 792 | */ 793 | PF_PFXNA = (1 << 13), 794 | 795 | /* 796 | the instruction supports vectored sib vm32x (AVX2+) 797 | */ 798 | PF_VSIB_X = (1 << 14), 799 | 800 | /* 801 | the instruction supports vectored sib vm32y (AVX2+) 802 | */ 803 | PF_VSIB_Y = (1 << 15), 804 | 805 | /* 806 | the instruction supports vectored sib vm32z (AVX2+) 807 | */ 808 | PF_VSIB_Z = (1 << 16), 809 | 810 | /* 811 | the instruction supports vectored sib vm32x/y/z based on L (AVX2+) 812 | */ 813 | PF_VSIB_L = (1 << 17), 814 | 815 | /* 816 | sign-extension for imm8/16/32 817 | */ 818 | PF_SIGN = (1 << 18) 819 | 820 | }; 821 | 822 | /**************************************************************************** 823 | 824 | table indexes and lookup methods 825 | 826 | ****************************************************************************/ 827 | 828 | #define TABLE_ID(i) TABLE_ID_##i 829 | #define TABLE_LOOKUP_METHOD(i) TABLE_LM_##i 830 | 831 | enum 832 | { 833 | /* addressing size: 0 = 16-bits, 1 = 32-bits, 2 = 64-bits */ 834 | TABLE_LOOKUP_METHOD(ASIZE) = 0, 835 | 836 | /* operand size: 0 = 16-bits, 1 = 32-bits, 2 = 64-bits */ 837 | TABLE_LOOKUP_METHOD(OSIZE), 838 | 839 | /* operand size: 0 = vex.w0, 1 = vex.w1 */ 840 | TABLE_LOOKUP_METHOD(OSIZE_VEX), 841 | 842 | /* operand size: 0 = xop.w0, 1 = xop.w1 */ 843 | TABLE_LOOKUP_METHOD(OSIZE_XOP), 844 | 845 | /* dasm mode: 0 = 16-bits, 1 = 32-bits, 2 = 64-bits */ 846 | TABLE_LOOKUP_METHOD(DMODE), 847 | 848 | /* modr/m byte reg/nnn field */ 849 | TABLE_LOOKUP_METHOD(MODRM_REG), 850 | 851 | /* modr/m byte r/m field */ 852 | TABLE_LOOKUP_METHOD(MODRM_RM), 853 | 854 | /* modr/m byte mod field: 0 = !11b, 1 = 11b */ 855 | TABLE_LOOKUP_METHOD(MODRM_MOD), 856 | 857 | /* modr/m byte: index = modr/m byte - C0h */ 858 | TABLE_LOOKUP_METHOD(FPU), 859 | 860 | /* last immediate byte is the opcode */ 861 | TABLE_LOOKUP_METHOD(3DNOW), 862 | 863 | /* byte */ 864 | TABLE_LOOKUP_METHOD(BYTE) 865 | }; 866 | 867 | enum 868 | { 869 | /* 1-byte table ids */ 870 | TABLE_ID(1B) = 0, 871 | TABLE_ID(60), 872 | TABLE_ID(61), 873 | TABLE_ID(63), 874 | TABLE_ID(6D), 875 | TABLE_ID(6F), 876 | TABLE_ID(80), 877 | TABLE_ID(81), 878 | TABLE_ID(82), 879 | TABLE_ID(83), 880 | TABLE_ID(8F), 881 | TABLE_ID(98), 882 | TABLE_ID(99), 883 | TABLE_ID(9C), 884 | TABLE_ID(9D), 885 | TABLE_ID(A5), 886 | TABLE_ID(A7), 887 | TABLE_ID(AB), 888 | TABLE_ID(AD), 889 | TABLE_ID(AF), 890 | TABLE_ID(C0), 891 | TABLE_ID(C1), 892 | TABLE_ID(C6), 893 | TABLE_ID(C7), 894 | TABLE_ID(CF), 895 | TABLE_ID(D0), 896 | TABLE_ID(D1), 897 | TABLE_ID(D2), 898 | TABLE_ID(D3), 899 | TABLE_ID(D8), 900 | TABLE_ID(D9), 901 | TABLE_ID(DA), 902 | TABLE_ID(DB), 903 | TABLE_ID(DC), 904 | TABLE_ID(DD), 905 | TABLE_ID(DE), 906 | TABLE_ID(DF), 907 | TABLE_ID(E3), 908 | TABLE_ID(F6), 909 | TABLE_ID(F7), 910 | TABLE_ID(FE), 911 | TABLE_ID(FF), 912 | TABLE_ID(D8_MOD_N11), 913 | TABLE_ID(D8_MOD_11), 914 | TABLE_ID(D9_MOD_N11), 915 | TABLE_ID(D9_MOD_11), 916 | TABLE_ID(DA_MOD_N11), 917 | TABLE_ID(DA_MOD_11), 918 | TABLE_ID(DB_MOD_N11), 919 | TABLE_ID(DB_MOD_11), 920 | TABLE_ID(DC_MOD_N11), 921 | TABLE_ID(DC_MOD_11), 922 | TABLE_ID(DD_MOD_N11), 923 | TABLE_ID(DD_MOD_11), 924 | TABLE_ID(DE_MOD_N11), 925 | TABLE_ID(DE_MOD_11), 926 | TABLE_ID(DF_MOD_N11), 927 | TABLE_ID(DF_MOD_11), 928 | 929 | /* 2-byte table ids */ 930 | TABLE_ID(0F), 931 | TABLE_ID(0F_00), 932 | TABLE_ID(0F_01), 933 | TABLE_ID(0F_0D), 934 | TABLE_ID(0F_0F), /* 3DNow! */ 935 | TABLE_ID(0F_12), 936 | TABLE_ID(0F_16), 937 | TABLE_ID(0F_18), 938 | TABLE_ID(0F_19), 939 | TABLE_ID(0F_1C), 940 | TABLE_ID(0F_1D), 941 | TABLE_ID(0F_1E), 942 | TABLE_ID(0F_1F), 943 | TABLE_ID(0F_6E), 944 | TABLE_ID(0F_71), 945 | TABLE_ID(0F_71_REG2), 946 | TABLE_ID(0F_71_REG4), 947 | TABLE_ID(0F_71_REG6), 948 | TABLE_ID(0F_72), 949 | TABLE_ID(0F_72_REG2), 950 | TABLE_ID(0F_72_REG4), 951 | TABLE_ID(0F_72_REG6), 952 | TABLE_ID(0F_73), 953 | TABLE_ID(0F_73_REG2), 954 | TABLE_ID(0F_73_REG6), 955 | TABLE_ID(0F_7E), 956 | TABLE_ID(0F_AE), 957 | TABLE_ID(0F_B9), 958 | TABLE_ID(0F_BA), 959 | TABLE_ID(0F_C4), 960 | TABLE_ID(0F_C7), 961 | TABLE_ID(0F_00_REG0), 962 | TABLE_ID(0F_00_REG1), 963 | TABLE_ID(0F_01_REG0), 964 | TABLE_ID(0F_01_REG1), 965 | TABLE_ID(0F_01_REG2), 966 | TABLE_ID(0F_01_REG3), 967 | TABLE_ID(0F_01_REG4), 968 | TABLE_ID(0F_01_REG7), 969 | TABLE_ID(0F_01_REG0_RM), 970 | TABLE_ID(0F_01_REG1_RM), 971 | TABLE_ID(0F_01_REG2_RM), 972 | TABLE_ID(0F_01_REG3_RM), 973 | TABLE_ID(0F_01_REG7_RM), 974 | TABLE_ID(0F_18_REG0), 975 | TABLE_ID(0F_18_REG1), 976 | TABLE_ID(0F_18_REG2), 977 | TABLE_ID(0F_18_REG3), 978 | TABLE_ID(0F_AE_REG0), 979 | TABLE_ID(0F_AE_REG1), 980 | TABLE_ID(0F_AE_REG2), 981 | TABLE_ID(0F_AE_REG3), 982 | TABLE_ID(0F_AE_REG4), 983 | TABLE_ID(0F_AE_REG5), 984 | TABLE_ID(0F_AE_REG6), 985 | TABLE_ID(0F_AE_REG7), 986 | TABLE_ID(0F_C7_REG1), 987 | TABLE_ID(0F_C7_REG3), 988 | TABLE_ID(0F_C7_REG4), 989 | TABLE_ID(0F_C7_REG5), 990 | TABLE_ID(0F_C7_REG6), 991 | TABLE_ID(0F_C7_REG7), 992 | TABLE_ID(66_0F), 993 | TABLE_ID(66_0F_19), 994 | TABLE_ID(66_0F_1C), 995 | TABLE_ID(66_0F_1D), 996 | TABLE_ID(66_0F_1E), 997 | TABLE_ID(66_0F_1F), 998 | TABLE_ID(66_0F_6E), 999 | TABLE_ID(66_0F_71), 1000 | TABLE_ID(66_0F_71_REG2), 1001 | TABLE_ID(66_0F_71_REG4), 1002 | TABLE_ID(66_0F_71_REG6), 1003 | TABLE_ID(66_0F_72), 1004 | TABLE_ID(66_0F_72_REG2), 1005 | TABLE_ID(66_0F_72_REG4), 1006 | TABLE_ID(66_0F_72_REG6), 1007 | TABLE_ID(66_0F_73), 1008 | TABLE_ID(66_0F_73_REG2), 1009 | TABLE_ID(66_0F_73_REG3), 1010 | TABLE_ID(66_0F_73_REG6), 1011 | TABLE_ID(66_0F_73_REG7), 1012 | TABLE_ID(66_0F_78), 1013 | TABLE_ID(66_0F_7E), 1014 | TABLE_ID(66_0F_AE), 1015 | TABLE_ID(66_0F_C4), 1016 | TABLE_ID(66_0F_C7), 1017 | TABLE_ID(66_0F_C7_REG6), 1018 | TABLE_ID(F3_0F), 1019 | TABLE_ID(F3_0F_01), 1020 | TABLE_ID(F3_0F_01_REG5), 1021 | TABLE_ID(F3_0F_01_REG5_RM), 1022 | TABLE_ID(F3_0F_19), 1023 | TABLE_ID(F3_0F_1C), 1024 | TABLE_ID(F3_0F_1D), 1025 | TABLE_ID(F3_0F_1E), 1026 | TABLE_ID(F3_0F_1E_REG1), 1027 | TABLE_ID(F3_0F_1E_REG7_RM), 1028 | TABLE_ID(F3_0F_1F), 1029 | TABLE_ID(F3_0F_71), 1030 | TABLE_ID(F3_0F_72), 1031 | TABLE_ID(F3_0F_73), 1032 | TABLE_ID(F3_0F_AE), 1033 | TABLE_ID(F3_0F_AE_REG5), 1034 | TABLE_ID(F3_0F_C7), 1035 | TABLE_ID(F3_0F_C7_REG6), 1036 | TABLE_ID(F3_0F_C7_REG7), 1037 | TABLE_ID(F2_0F), 1038 | TABLE_ID(F2_0F_19), 1039 | TABLE_ID(F2_0F_1C), 1040 | TABLE_ID(F2_0F_1D), 1041 | TABLE_ID(F2_0F_1E), 1042 | TABLE_ID(F2_0F_1F), 1043 | TABLE_ID(F2_0F_71), 1044 | TABLE_ID(F2_0F_72), 1045 | TABLE_ID(F2_0F_73), 1046 | TABLE_ID(F2_0F_AE), 1047 | 1048 | /* 3-byte table ids */ 1049 | TABLE_ID(0F_38), 1050 | TABLE_ID(0F_38_F3), 1051 | TABLE_ID(0F_38_F6), 1052 | TABLE_ID(0F_3A), 1053 | TABLE_ID(66_0F_38), 1054 | TABLE_ID(66_0F_38_20), 1055 | TABLE_ID(66_0F_38_21), 1056 | TABLE_ID(66_0F_38_22), 1057 | TABLE_ID(66_0F_38_23), 1058 | TABLE_ID(66_0F_38_24), 1059 | TABLE_ID(66_0F_38_25), 1060 | TABLE_ID(66_0F_38_30), 1061 | TABLE_ID(66_0F_38_31), 1062 | TABLE_ID(66_0F_38_32), 1063 | TABLE_ID(66_0F_38_33), 1064 | TABLE_ID(66_0F_38_34), 1065 | TABLE_ID(66_0F_38_35), 1066 | TABLE_ID(66_0F_38_45), 1067 | TABLE_ID(66_0F_38_47), 1068 | TABLE_ID(66_0F_38_8C), 1069 | TABLE_ID(66_0F_38_8E), 1070 | TABLE_ID(66_0F_38_90), 1071 | TABLE_ID(66_0F_38_91), 1072 | TABLE_ID(66_0F_38_92), 1073 | TABLE_ID(66_0F_38_93), 1074 | TABLE_ID(66_0F_38_96), 1075 | TABLE_ID(66_0F_38_97), 1076 | TABLE_ID(66_0F_38_98), 1077 | TABLE_ID(66_0F_38_99), 1078 | TABLE_ID(66_0F_38_9A), 1079 | TABLE_ID(66_0F_38_9B), 1080 | TABLE_ID(66_0F_38_9C), 1081 | TABLE_ID(66_0F_38_9D), 1082 | TABLE_ID(66_0F_38_9E), 1083 | TABLE_ID(66_0F_38_9F), 1084 | TABLE_ID(66_0F_38_A6), 1085 | TABLE_ID(66_0F_38_A7), 1086 | TABLE_ID(66_0F_38_A8), 1087 | TABLE_ID(66_0F_38_A9), 1088 | TABLE_ID(66_0F_38_AA), 1089 | TABLE_ID(66_0F_38_AB), 1090 | TABLE_ID(66_0F_38_AC), 1091 | TABLE_ID(66_0F_38_AD), 1092 | TABLE_ID(66_0F_38_AE), 1093 | TABLE_ID(66_0F_38_AF), 1094 | TABLE_ID(66_0F_38_B6), 1095 | TABLE_ID(66_0F_38_B7), 1096 | TABLE_ID(66_0F_38_B8), 1097 | TABLE_ID(66_0F_38_B9), 1098 | TABLE_ID(66_0F_38_BA), 1099 | TABLE_ID(66_0F_38_BB), 1100 | TABLE_ID(66_0F_38_BC), 1101 | TABLE_ID(66_0F_38_BD), 1102 | TABLE_ID(66_0F_38_BE), 1103 | TABLE_ID(66_0F_38_BF), 1104 | TABLE_ID(66_0F_38_F5), 1105 | TABLE_ID(66_0F_3A), 1106 | TABLE_ID(66_0F_3A_14), 1107 | TABLE_ID(66_0F_3A_15), 1108 | TABLE_ID(66_0F_3A_16), 1109 | TABLE_ID(66_0F_3A_20), 1110 | TABLE_ID(66_0F_3A_21), 1111 | TABLE_ID(66_0F_3A_22), 1112 | TABLE_ID(F3_0F_38), 1113 | TABLE_ID(F3_0F_3A), 1114 | TABLE_ID(F2_0F_38), 1115 | TABLE_ID(F2_0F_3A), 1116 | 1117 | /* XOP */ 1118 | TABLE_ID(XOP_8), 1119 | TABLE_ID(XOP_8_A2), 1120 | TABLE_ID(XOP_8_A3), 1121 | TABLE_ID(XOP_9), 1122 | TABLE_ID(XOP_9_1), 1123 | TABLE_ID(XOP_9_2), 1124 | TABLE_ID(XOP_9_12), 1125 | TABLE_ID(XOP_9_90), 1126 | TABLE_ID(XOP_9_91), 1127 | TABLE_ID(XOP_9_92), 1128 | TABLE_ID(XOP_9_93), 1129 | TABLE_ID(XOP_9_94), 1130 | TABLE_ID(XOP_9_95), 1131 | TABLE_ID(XOP_9_96), 1132 | TABLE_ID(XOP_9_97), 1133 | TABLE_ID(XOP_9_98), 1134 | TABLE_ID(XOP_9_99), 1135 | TABLE_ID(XOP_9_9A), 1136 | TABLE_ID(XOP_9_9B), 1137 | TABLE_ID(XOP_A), 1138 | TABLE_ID(XOP_A_12), 1139 | 1140 | /* FMA4 */ 1141 | TABLE_ID(66_0F_3A_69), 1142 | 1143 | TABLE_ID(66_0F_3A_5C), 1144 | TABLE_ID(66_0F_3A_5D), 1145 | TABLE_ID(66_0F_3A_5E), 1146 | TABLE_ID(66_0F_3A_5F), 1147 | TABLE_ID(66_0F_3A_68), 1148 | TABLE_ID(66_0F_3A_6A), 1149 | TABLE_ID(66_0F_3A_6B), 1150 | TABLE_ID(66_0F_3A_6C), 1151 | TABLE_ID(66_0F_3A_6D), 1152 | TABLE_ID(66_0F_3A_6E), 1153 | TABLE_ID(66_0F_3A_6F), 1154 | TABLE_ID(66_0F_3A_78), 1155 | TABLE_ID(66_0F_3A_79), 1156 | TABLE_ID(66_0F_3A_7A), 1157 | TABLE_ID(66_0F_3A_7B), 1158 | TABLE_ID(66_0F_3A_7C), 1159 | TABLE_ID(66_0F_3A_7D), 1160 | TABLE_ID(66_0F_3A_7E), 1161 | TABLE_ID(66_0F_3A_7F), 1162 | 1163 | /* do not use to dereference! */ 1164 | TABLE_ID(NONE) 1165 | }; 1166 | 1167 | /**************************************************************************** 1168 | 1169 | table structs 1170 | 1171 | ****************************************************************************/ 1172 | 1173 | typedef struct 1174 | { 1175 | uint8_t am; /* addressing method */ 1176 | uint8_t ot; /* operand type */ 1177 | 1178 | } x86_table_operand_t; 1179 | 1180 | typedef struct 1181 | { 1182 | uint16_t table_id; /* table id */ 1183 | uint8_t iset; /* instruction set */ 1184 | uint16_t mnem_id; /* mnemonic id */ 1185 | 1186 | #if !defined(X86_DASM_NOFMT) || defined(X86_DASM_DEBUG) 1187 | 1188 | char* mnem_str; /* mnemonic string */ 1189 | 1190 | #endif 1191 | 1192 | uint32_t properties; /* properties */ 1193 | x86_table_operand_t operands[4]; /* operands */ 1194 | 1195 | } x86_table_entry_t; 1196 | 1197 | typedef struct 1198 | { 1199 | 1200 | #if defined(X86_DASM_DEBUG) 1201 | 1202 | char* table_name; 1203 | 1204 | #endif 1205 | 1206 | const x86_table_entry_t* table; 1207 | uint8_t lookup_method; 1208 | 1209 | } x86_table_link_t; 1210 | 1211 | /**************************************************************************** 1212 | 1213 | macro acrobatics to overload the OP() macro 1214 | 1215 | ****************************************************************************/ 1216 | 1217 | #define EXPAND(x) x 1218 | #define OPERAND(x) {x} 1219 | 1220 | #define OP_0 { \ 1221 | OPERAND(O_NONE), \ 1222 | OPERAND(O_NONE), \ 1223 | OPERAND(O_NONE), \ 1224 | OPERAND(O_NONE) } 1225 | 1226 | #define OP_1(_1) { \ 1227 | OPERAND(O_##_1), \ 1228 | OPERAND(O_NONE), \ 1229 | OPERAND(O_NONE), \ 1230 | OPERAND(O_NONE) } 1231 | 1232 | #define OP_2(_1, _2) { \ 1233 | OPERAND(O_##_1), \ 1234 | OPERAND(O_##_2), \ 1235 | OPERAND(O_NONE), \ 1236 | OPERAND(O_NONE) } 1237 | 1238 | #define OP_3(_1, _2, _3) { \ 1239 | OPERAND(O_##_1), \ 1240 | OPERAND(O_##_2), \ 1241 | OPERAND(O_##_3), \ 1242 | OPERAND(O_NONE) } 1243 | 1244 | #define OP_4(_1, _2, _3, _4) { \ 1245 | OPERAND(O_##_1), \ 1246 | OPERAND(O_##_2), \ 1247 | OPERAND(O_##_3), \ 1248 | OPERAND(O_##_4) } 1249 | 1250 | #define PP_NARG(...) EXPAND(PP_NARG_(__VA_ARGS__, PP_RSEQ_N())) 1251 | #define PP_NARG_(...) EXPAND(PP_ARG_N(__VA_ARGS__)) 1252 | #define PP_ARG_N(_1, _2, _3, _4, N, ...) N 1253 | #define PP_RSEQ_N() 4, 3, 2, 1, 0 1254 | 1255 | #define OP_(N) OP_##N 1256 | #define OP_EVAL(N) OP_(N) 1257 | 1258 | #define OP(...) \ 1259 | EXPAND(OP_EVAL(EXPAND(PP_NARG(__VA_ARGS__)))(__VA_ARGS__)) 1260 | 1261 | /**************************************************************************** 1262 | 1263 | table macros 1264 | 1265 | ****************************************************************************/ 1266 | 1267 | #define TABLE_NAME(_1) table_##_1 1268 | 1269 | #define TABLE_BEGIN(_1) \ 1270 | static const x86_table_entry_t TABLE_NAME(_1)[] = { 1271 | 1272 | #define TABLE_END(_1) \ 1273 | }; 1274 | 1275 | #if !defined(X86_DASM_NOFMT) || defined(X86_DASM_DEBUG) 1276 | 1277 | #define TABLE_ENTRY(_1, _2, _3, _4, _5) { \ 1278 | /* table id */ TABLE_ID(NONE), \ 1279 | /* instruction set */ _4, \ 1280 | /* mnemonic id */ _2, \ 1281 | /* mnemonic string */ _1, \ 1282 | /* properties */ _3, \ 1283 | /* operands */ _5, } 1284 | 1285 | #define TABLE_ENTRY_INVALID() { \ 1286 | /* table id */ TABLE_ID(NONE), \ 1287 | /* instruction set */ X86_ISET_NONE, \ 1288 | /* mnemonic id */ X86_MN_INVALID, \ 1289 | /* mnemonic string */ NULL, \ 1290 | /* properties */ PF_NONE, \ 1291 | /* operands */ OP_0 } 1292 | 1293 | #define TABLE_ENTRY_ESCAPE(_1) { \ 1294 | /* table id */ TABLE_ID(_1), \ 1295 | /* instruction set */ X86_ISET_NONE, \ 1296 | /* mnemonic id */ X86_MN_INVALID, \ 1297 | /* mnemonic string */ NULL, \ 1298 | /* properties */ PF_NONE, \ 1299 | /* operands */ OP_0 } 1300 | 1301 | #else 1302 | 1303 | #define TABLE_ENTRY(_1, _2, _3, _4, _5) { \ 1304 | /* table id */ TABLE_ID(NONE), \ 1305 | /* instruction set */ _4, \ 1306 | /* mnemonic id */ _2, \ 1307 | /* properties */ _3, \ 1308 | /* operands */ _5, } 1309 | 1310 | #define TABLE_ENTRY_INVALID() { \ 1311 | /* table id */ TABLE_ID(NONE), \ 1312 | /* instruction set */ X86_ISET_NONE, \ 1313 | /* mnemonic id */ X86_MN_INVALID, \ 1314 | /* properties */ PF_NONE, \ 1315 | /* operands */ OP_0 } 1316 | 1317 | #define TABLE_ENTRY_ESCAPE(_1) { \ 1318 | /* table id */ TABLE_ID(_1), \ 1319 | /* instruction set */ X86_ISET_NONE, \ 1320 | /* mnemonic id */ X86_MN_INVALID, \ 1321 | /* properties */ PF_NONE, \ 1322 | /* operands */ OP_0 } 1323 | 1324 | #endif 1325 | 1326 | #if defined(X86_DASM_DEBUG) 1327 | 1328 | #define TABLE_LINK(_1, _2) { \ 1329 | /* table_name */ #_1, \ 1330 | /* table */ TABLE_NAME(_1), \ 1331 | /* lookup method */ TABLE_LOOKUP_METHOD(_2) } 1332 | 1333 | #else 1334 | 1335 | #define TABLE_LINK(_1, _2) { \ 1336 | /* table */ TABLE_NAME(_1), \ 1337 | /* lookup method */ TABLE_LOOKUP_METHOD(_2) } 1338 | 1339 | #endif 1340 | 1341 | #define EFLAGS_ENTRY(_1, _2, _3, _4, _5, _6, _7, _8) \ 1342 | { X86_FLAG_##_1, X86_FLAG_##_2, X86_FLAG_##_3, X86_FLAG_##_4, \ 1343 | X86_FLAG_##_5, X86_FLAG_##_6, X86_FLAG_##_7, X86_FLAG_##_8 } 1344 | 1345 | /**************************************************************************** 1346 | 1347 | declarations / exports 1348 | 1349 | ****************************************************************************/ 1350 | 1351 | typedef struct 1352 | { 1353 | uint8_t o : 3; /* overflow flag */ 1354 | uint8_t d : 3; /* direction flag */ 1355 | uint8_t i : 3; /* interrupt flag */ 1356 | uint8_t s : 3; /* sign flag */ 1357 | uint8_t z : 3; /* zero flag */ 1358 | uint8_t a : 3; /* aux carry flag */ 1359 | uint8_t p : 3; /* parity flag */ 1360 | uint8_t c : 3; /* carry flag */ 1361 | 1362 | } x86_eflags_t; 1363 | 1364 | extern const x86_table_link_t x86_table_links[]; 1365 | extern const x86_eflags_t x86_eflags_table[]; 1366 | 1367 | x86_eflags_t x86_eflags_get(uint16_t mnem); 1368 | 1369 | #ifdef __cplusplus 1370 | } 1371 | #endif 1372 | 1373 | #endif //_DASM_H_ -------------------------------------------------------------------------------- /obj/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejanit0r/x86_dasm/20dd43fb4589c5e41160ed6279cd3041f766f400/obj/.gitkeep -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file is part of x86_dasm. 4 | 5 | x86_dasm is a compact x86-64 disassembling library 6 | 7 | Copyright 2014 / the`janitor / < email: base64dec(dGhlLmphbml0b3JAcHJvdG9ubWFpbC5jb20=) > 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | */ 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "x86_dasm.h" 31 | 32 | void 33 | usage(char* progname) 34 | { 35 | printf("\n" 36 | "****************************************************\n" 37 | "* *\n" 38 | "* x86-64 disassembler *\n" 39 | "* ********************* *\n" 40 | "* the`janitor *\n" 41 | "* *\n" 42 | "****************************************************\n\n"); 43 | 44 | printf("Usage: %s -f -m <16|32|64> [-i ] [-h]\n", 45 | progname); 46 | } 47 | 48 | int 49 | main(int argc, char* argv[]) 50 | { 51 | /* file path to disasm */ 52 | char* filename = NULL; 53 | 54 | /* instruction pointer */ 55 | uint64_t rip = 0; 56 | 57 | /* disasm mode */ 58 | ulong_t dmode = 0; 59 | 60 | x86_dasm_context_t x86_dctx; 61 | 62 | /* clear the dasm context */ 63 | memset(&x86_dctx, 0, sizeof(x86_dctx)); 64 | 65 | for(int c; (c = getopt(argc, argv, "f:m:i:h")) != -1; ) 66 | { 67 | switch(c) 68 | { 69 | case 'h': 70 | usage(argv[0]); 71 | return EXIT_SUCCESS; 72 | case 'i': 73 | rip = strtoull(optarg, NULL, 16); 74 | break; 75 | case 'f': 76 | filename = optarg; 77 | break; 78 | case 'm': 79 | dmode = strtoul(optarg, NULL, 10); 80 | break; 81 | case '?': 82 | printf("Option -%c requires an argument\n", optopt); 83 | return EXIT_FAILURE; 84 | default: 85 | break; 86 | } 87 | 88 | /* exit on bad arguments */ 89 | if(errno != 0) 90 | { 91 | printf("Bad argument for option -%c\n", c); 92 | return EXIT_FAILURE; 93 | } 94 | } 95 | 96 | /* check that the file path was provided */ 97 | if(filename == NULL) 98 | { 99 | printf("No file name provided\n"); 100 | usage(argv[0]); 101 | return EXIT_FAILURE; 102 | } 103 | 104 | /* check that the disasm mode was provided */ 105 | switch(dmode) 106 | { 107 | case 16: x86_dctx.dmode = X86_DMODE_16BIT; break; 108 | case 32: x86_dctx.dmode = X86_DMODE_32BIT; break; 109 | case 64: x86_dctx.dmode = X86_DMODE_64BIT; break; 110 | default: 111 | printf("Invalid disasm mode\n"); 112 | usage(argv[0]); 113 | return EXIT_FAILURE; 114 | } 115 | 116 | FILE* fd; 117 | ulong_t fsize; 118 | ulong_t j = 0; 119 | 120 | /* open the raw binary file */ 121 | if((fd = fopen(filename, "rb")) == NULL) 122 | { 123 | printf("Failed to open %s\n", filename); 124 | return EXIT_FAILURE; 125 | } 126 | 127 | /* get the file size */ 128 | fseek(fd, 0, SEEK_END); fsize = ftell(fd); 129 | rewind(fd); 130 | 131 | /* allocate enough memory */ 132 | uint8_t* code = (uint8_t *)malloc(fsize * sizeof(uint8_t)); 133 | 134 | if(code == NULL) 135 | { 136 | printf("Failed to allocate memory\n"); 137 | return EXIT_FAILURE; 138 | } 139 | 140 | /* read the binary file into memory */ 141 | fread(code, 1, fsize, fd); 142 | fclose(fd); 143 | 144 | /* disassemble the code */ 145 | while(j < fsize) 146 | { 147 | x86_set_buffer(&x86_dctx, &code[j]); 148 | x86_set_ip(&x86_dctx, rip + j); 149 | 150 | if(x86_dasm(&x86_dctx) < 0) 151 | { 152 | printf("Failed to disasm\n"); 153 | 154 | return EXIT_FAILURE; 155 | } 156 | else 157 | { 158 | printf("%04" PRIX64 " | ", rip + j); 159 | 160 | /* print the bytes */ 161 | for(int i = 0; i < 16 - x86_dctx.len; i++) 162 | printf(" "); 163 | 164 | for(int i = 0; i < x86_dctx.len; i++) 165 | printf("%02X ", x86_dctx.buffer[i]); 166 | 167 | /* print the decoded instruction */ 168 | printf(" | %s\n", x86_dctx.inst_str); 169 | 170 | j += x86_dctx.len; 171 | } 172 | } 173 | 174 | free(code); 175 | 176 | return EXIT_SUCCESS; 177 | } 178 | 179 | /***************************************************************************/ 180 | 181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /test/test-x32.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejanit0r/x86_dasm/20dd43fb4589c5e41160ed6279cd3041f766f400/test/test-x32.bin -------------------------------------------------------------------------------- /test/test-x64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejanit0r/x86_dasm/20dd43fb4589c5e41160ed6279cd3041f766f400/test/test-x64.bin --------------------------------------------------------------------------------