aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/lib')
-rw-r--r--arch/x86/lib/Makefile13
-rw-r--r--arch/x86/lib/inat.c78
-rw-r--r--arch/x86/lib/insn.c464
-rw-r--r--arch/x86/lib/x86-opcode-map.txt719
4 files changed, 1274 insertions, 0 deletions
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 07c31899c9c2..c77f8a7c531d 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -2,12 +2,25 @@
2# Makefile for x86 specific library files. 2# Makefile for x86 specific library files.
3# 3#
4 4
5inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
6inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
7quiet_cmd_inat_tables = GEN $@
8 cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@
9
10$(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
11 $(call cmd,inat_tables)
12
13$(obj)/inat.o: $(obj)/inat-tables.c
14
15clean-files := inat-tables.c
16
5obj-$(CONFIG_SMP) := msr.o 17obj-$(CONFIG_SMP) := msr.o
6 18
7lib-y := delay.o 19lib-y := delay.o
8lib-y += thunk_$(BITS).o 20lib-y += thunk_$(BITS).o
9lib-y += usercopy_$(BITS).o getuser.o putuser.o 21lib-y += usercopy_$(BITS).o getuser.o putuser.o
10lib-y += memcpy_$(BITS).o 22lib-y += memcpy_$(BITS).o
23lib-y += insn.o inat.o
11 24
12ifeq ($(CONFIG_X86_32),y) 25ifeq ($(CONFIG_X86_32),y)
13 obj-y += atomic64_32.o 26 obj-y += atomic64_32.o
diff --git a/arch/x86/lib/inat.c b/arch/x86/lib/inat.c
new file mode 100644
index 000000000000..054656a01dfd
--- /dev/null
+++ b/arch/x86/lib/inat.c
@@ -0,0 +1,78 @@
1/*
2 * x86 instruction attribute tables
3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21#include <asm/insn.h>
22
23/* Attribute tables are generated from opcode map */
24#include "inat-tables.c"
25
26/* Attribute search APIs */
27insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode)
28{
29 return inat_primary_table[opcode];
30}
31
32insn_attr_t inat_get_escape_attribute(insn_byte_t opcode, insn_byte_t last_pfx,
33 insn_attr_t esc_attr)
34{
35 const insn_attr_t *table;
36 insn_attr_t lpfx_attr;
37 int n, m = 0;
38
39 n = inat_escape_id(esc_attr);
40 if (last_pfx) {
41 lpfx_attr = inat_get_opcode_attribute(last_pfx);
42 m = inat_last_prefix_id(lpfx_attr);
43 }
44 table = inat_escape_tables[n][0];
45 if (!table)
46 return 0;
47 if (inat_has_variant(table[opcode]) && m) {
48 table = inat_escape_tables[n][m];
49 if (!table)
50 return 0;
51 }
52 return table[opcode];
53}
54
55insn_attr_t inat_get_group_attribute(insn_byte_t modrm, insn_byte_t last_pfx,
56 insn_attr_t grp_attr)
57{
58 const insn_attr_t *table;
59 insn_attr_t lpfx_attr;
60 int n, m = 0;
61
62 n = inat_group_id(grp_attr);
63 if (last_pfx) {
64 lpfx_attr = inat_get_opcode_attribute(last_pfx);
65 m = inat_last_prefix_id(lpfx_attr);
66 }
67 table = inat_group_tables[n][0];
68 if (!table)
69 return inat_group_common_attribute(grp_attr);
70 if (inat_has_variant(table[X86_MODRM_REG(modrm)]) && m) {
71 table = inat_escape_tables[n][m];
72 if (!table)
73 return inat_group_common_attribute(grp_attr);
74 }
75 return table[X86_MODRM_REG(modrm)] |
76 inat_group_common_attribute(grp_attr);
77}
78
diff --git a/arch/x86/lib/insn.c b/arch/x86/lib/insn.c
new file mode 100644
index 000000000000..dfd56a30053f
--- /dev/null
+++ b/arch/x86/lib/insn.c
@@ -0,0 +1,464 @@
1/*
2 * x86 instruction analysis
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) IBM Corporation, 2002, 2004, 2009
19 */
20
21#include <linux/string.h>
22#include <asm/inat.h>
23#include <asm/insn.h>
24
25#define get_next(t, insn) \
26 ({t r; r = *(t*)insn->next_byte; insn->next_byte += sizeof(t); r; })
27
28#define peek_next(t, insn) \
29 ({t r; r = *(t*)insn->next_byte; r; })
30
31/**
32 * insn_init() - initialize struct insn
33 * @insn: &struct insn to be initialized
34 * @kaddr: address (in kernel memory) of instruction (or copy thereof)
35 * @x86_64: !0 for 64-bit kernel or 64-bit app
36 */
37void insn_init(struct insn *insn, const void *kaddr, int x86_64)
38{
39 memset(insn, 0, sizeof(*insn));
40 insn->kaddr = kaddr;
41 insn->next_byte = kaddr;
42 insn->x86_64 = x86_64 ? 1 : 0;
43 insn->opnd_bytes = 4;
44 if (x86_64)
45 insn->addr_bytes = 8;
46 else
47 insn->addr_bytes = 4;
48}
49
50/**
51 * insn_get_prefixes - scan x86 instruction prefix bytes
52 * @insn: &struct insn containing instruction
53 *
54 * Populates the @insn->prefixes bitmap, and updates @insn->next_byte
55 * to point to the (first) opcode. No effect if @insn->prefixes.got
56 * is already set.
57 */
58void insn_get_prefixes(struct insn *insn)
59{
60 struct insn_field *prefixes = &insn->prefixes;
61 insn_attr_t attr;
62 insn_byte_t b, lb;
63 int i, nb;
64
65 if (prefixes->got)
66 return;
67
68 nb = 0;
69 lb = 0;
70 b = peek_next(insn_byte_t, insn);
71 attr = inat_get_opcode_attribute(b);
72 while (inat_is_prefix(attr)) {
73 /* Skip if same prefix */
74 for (i = 0; i < nb; i++)
75 if (prefixes->bytes[i] == b)
76 goto found;
77 if (nb == 4)
78 /* Invalid instruction */
79 break;
80 prefixes->bytes[nb++] = b;
81 if (inat_is_address_size_prefix(attr)) {
82 /* address size switches 2/4 or 4/8 */
83 if (insn->x86_64)
84 insn->addr_bytes ^= 12;
85 else
86 insn->addr_bytes ^= 6;
87 } else if (inat_is_operand_size_prefix(attr)) {
88 /* oprand size switches 2/4 */
89 insn->opnd_bytes ^= 6;
90 }
91found:
92 prefixes->nbytes++;
93 insn->next_byte++;
94 lb = b;
95 b = peek_next(insn_byte_t, insn);
96 attr = inat_get_opcode_attribute(b);
97 }
98 /* Set the last prefix */
99 if (lb && lb != insn->prefixes.bytes[3]) {
100 if (unlikely(insn->prefixes.bytes[3])) {
101 /* Swap the last prefix */
102 b = insn->prefixes.bytes[3];
103 for (i = 0; i < nb; i++)
104 if (prefixes->bytes[i] == lb)
105 prefixes->bytes[i] = b;
106 }
107 insn->prefixes.bytes[3] = lb;
108 }
109
110 if (insn->x86_64) {
111 b = peek_next(insn_byte_t, insn);
112 attr = inat_get_opcode_attribute(b);
113 if (inat_is_rex_prefix(attr)) {
114 insn->rex_prefix.value = b;
115 insn->rex_prefix.nbytes = 1;
116 insn->next_byte++;
117 if (X86_REX_W(b))
118 /* REX.W overrides opnd_size */
119 insn->opnd_bytes = 8;
120 }
121 }
122 insn->rex_prefix.got = 1;
123 prefixes->got = 1;
124 return;
125}
126
127/**
128 * insn_get_opcode - collect opcode(s)
129 * @insn: &struct insn containing instruction
130 *
131 * Populates @insn->opcode, updates @insn->next_byte to point past the
132 * opcode byte(s), and set @insn->attr (except for groups).
133 * If necessary, first collects any preceding (prefix) bytes.
134 * Sets @insn->opcode.value = opcode1. No effect if @insn->opcode.got
135 * is already 1.
136 */
137void insn_get_opcode(struct insn *insn)
138{
139 struct insn_field *opcode = &insn->opcode;
140 insn_byte_t op, pfx;
141 if (opcode->got)
142 return;
143 if (!insn->prefixes.got)
144 insn_get_prefixes(insn);
145
146 /* Get first opcode */
147 op = get_next(insn_byte_t, insn);
148 opcode->bytes[0] = op;
149 opcode->nbytes = 1;
150 insn->attr = inat_get_opcode_attribute(op);
151 while (inat_is_escape(insn->attr)) {
152 /* Get escaped opcode */
153 op = get_next(insn_byte_t, insn);
154 opcode->bytes[opcode->nbytes++] = op;
155 pfx = insn_last_prefix(insn);
156 insn->attr = inat_get_escape_attribute(op, pfx, insn->attr);
157 }
158 opcode->got = 1;
159}
160
161/**
162 * insn_get_modrm - collect ModRM byte, if any
163 * @insn: &struct insn containing instruction
164 *
165 * Populates @insn->modrm and updates @insn->next_byte to point past the
166 * ModRM byte, if any. If necessary, first collects the preceding bytes
167 * (prefixes and opcode(s)). No effect if @insn->modrm.got is already 1.
168 */
169void insn_get_modrm(struct insn *insn)
170{
171 struct insn_field *modrm = &insn->modrm;
172 insn_byte_t pfx, mod;
173 if (modrm->got)
174 return;
175 if (!insn->opcode.got)
176 insn_get_opcode(insn);
177
178 if (inat_has_modrm(insn->attr)) {
179 mod = get_next(insn_byte_t, insn);
180 modrm->value = mod;
181 modrm->nbytes = 1;
182 if (inat_is_group(insn->attr)) {
183 pfx = insn_last_prefix(insn);
184 insn->attr = inat_get_group_attribute(mod, pfx,
185 insn->attr);
186 }
187 }
188
189 if (insn->x86_64 && inat_is_force64(insn->attr))
190 insn->opnd_bytes = 8;
191 modrm->got = 1;
192}
193
194
195/**
196 * insn_rip_relative() - Does instruction use RIP-relative addressing mode?
197 * @insn: &struct insn containing instruction
198 *
199 * If necessary, first collects the instruction up to and including the
200 * ModRM byte. No effect if @insn->x86_64 is 0.
201 */
202int insn_rip_relative(struct insn *insn)
203{
204 struct insn_field *modrm = &insn->modrm;
205
206 if (!insn->x86_64)
207 return 0;
208 if (!modrm->got)
209 insn_get_modrm(insn);
210 /*
211 * For rip-relative instructions, the mod field (top 2 bits)
212 * is zero and the r/m field (bottom 3 bits) is 0x5.
213 */
214 return (modrm->nbytes && (modrm->value & 0xc7) == 0x5);
215}
216
217/**
218 * insn_get_sib() - Get the SIB byte of instruction
219 * @insn: &struct insn containing instruction
220 *
221 * If necessary, first collects the instruction up to and including the
222 * ModRM byte.
223 */
224void insn_get_sib(struct insn *insn)
225{
226 insn_byte_t modrm;
227
228 if (insn->sib.got)
229 return;
230 if (!insn->modrm.got)
231 insn_get_modrm(insn);
232 if (insn->modrm.nbytes) {
233 modrm = (insn_byte_t)insn->modrm.value;
234 if (insn->addr_bytes != 2 &&
235 X86_MODRM_MOD(modrm) != 3 && X86_MODRM_RM(modrm) == 4) {
236 insn->sib.value = get_next(insn_byte_t, insn);
237 insn->sib.nbytes = 1;
238 }
239 }
240 insn->sib.got = 1;
241}
242
243
244/**
245 * insn_get_displacement() - Get the displacement of instruction
246 * @insn: &struct insn containing instruction
247 *
248 * If necessary, first collects the instruction up to and including the
249 * SIB byte.
250 * Displacement value is sign-expanded.
251 */
252void insn_get_displacement(struct insn *insn)
253{
254 insn_byte_t mod, rm, base;
255
256 if (insn->displacement.got)
257 return;
258 if (!insn->sib.got)
259 insn_get_sib(insn);
260 if (insn->modrm.nbytes) {
261 /*
262 * Interpreting the modrm byte:
263 * mod = 00 - no displacement fields (exceptions below)
264 * mod = 01 - 1-byte displacement field
265 * mod = 10 - displacement field is 4 bytes, or 2 bytes if
266 * address size = 2 (0x67 prefix in 32-bit mode)
267 * mod = 11 - no memory operand
268 *
269 * If address size = 2...
270 * mod = 00, r/m = 110 - displacement field is 2 bytes
271 *
272 * If address size != 2...
273 * mod != 11, r/m = 100 - SIB byte exists
274 * mod = 00, SIB base = 101 - displacement field is 4 bytes
275 * mod = 00, r/m = 101 - rip-relative addressing, displacement
276 * field is 4 bytes
277 */
278 mod = X86_MODRM_MOD(insn->modrm.value);
279 rm = X86_MODRM_RM(insn->modrm.value);
280 base = X86_SIB_BASE(insn->sib.value);
281 if (mod == 3)
282 goto out;
283 if (mod == 1) {
284 insn->displacement.value = get_next(char, insn);
285 insn->displacement.nbytes = 1;
286 } else if (insn->addr_bytes == 2) {
287 if ((mod == 0 && rm == 6) || mod == 2) {
288 insn->displacement.value =
289 get_next(short, insn);
290 insn->displacement.nbytes = 2;
291 }
292 } else {
293 if ((mod == 0 && rm == 5) || mod == 2 ||
294 (mod == 0 && base == 5)) {
295 insn->displacement.value = get_next(int, insn);
296 insn->displacement.nbytes = 4;
297 }
298 }
299 }
300out:
301 insn->displacement.got = 1;
302}
303
304/* Decode moffset16/32/64 */
305static void __get_moffset(struct insn *insn)
306{
307 switch (insn->addr_bytes) {
308 case 2:
309 insn->moffset1.value = get_next(short, insn);
310 insn->moffset1.nbytes = 2;
311 break;
312 case 4:
313 insn->moffset1.value = get_next(int, insn);
314 insn->moffset1.nbytes = 4;
315 break;
316 case 8:
317 insn->moffset1.value = get_next(int, insn);
318 insn->moffset1.nbytes = 4;
319 insn->moffset2.value = get_next(int, insn);
320 insn->moffset2.nbytes = 4;
321 break;
322 }
323 insn->moffset1.got = insn->moffset2.got = 1;
324}
325
326/* Decode imm v32(Iz) */
327static void __get_immv32(struct insn *insn)
328{
329 switch (insn->opnd_bytes) {
330 case 2:
331 insn->immediate.value = get_next(short, insn);
332 insn->immediate.nbytes = 2;
333 break;
334 case 4:
335 case 8:
336 insn->immediate.value = get_next(int, insn);
337 insn->immediate.nbytes = 4;
338 break;
339 }
340}
341
342/* Decode imm v64(Iv/Ov) */
343static void __get_immv(struct insn *insn)
344{
345 switch (insn->opnd_bytes) {
346 case 2:
347 insn->immediate1.value = get_next(short, insn);
348 insn->immediate1.nbytes = 2;
349 break;
350 case 4:
351 insn->immediate1.value = get_next(int, insn);
352 insn->immediate1.nbytes = 4;
353 break;
354 case 8:
355 insn->immediate1.value = get_next(int, insn);
356 insn->immediate1.nbytes = 4;
357 insn->immediate2.value = get_next(int, insn);
358 insn->immediate2.nbytes = 4;
359 break;
360 }
361 insn->immediate1.got = insn->immediate2.got = 1;
362}
363
364/* Decode ptr16:16/32(Ap) */
365static void __get_immptr(struct insn *insn)
366{
367 switch (insn->opnd_bytes) {
368 case 2:
369 insn->immediate1.value = get_next(short, insn);
370 insn->immediate1.nbytes = 2;
371 break;
372 case 4:
373 insn->immediate1.value = get_next(int, insn);
374 insn->immediate1.nbytes = 4;
375 break;
376 case 8:
377 /* ptr16:64 is not exist (no segment) */
378 return;
379 }
380 insn->immediate2.value = get_next(unsigned short, insn);
381 insn->immediate2.nbytes = 2;
382 insn->immediate1.got = insn->immediate2.got = 1;
383}
384
385/**
386 * insn_get_immediate() - Get the immediates of instruction
387 * @insn: &struct insn containing instruction
388 *
389 * If necessary, first collects the instruction up to and including the
390 * displacement bytes.
391 * Basically, most of immediates are sign-expanded. Unsigned-value can be
392 * get by bit masking with ((1 << (nbytes * 8)) - 1)
393 */
394void insn_get_immediate(struct insn *insn)
395{
396 if (insn->immediate.got)
397 return;
398 if (!insn->displacement.got)
399 insn_get_displacement(insn);
400
401 if (inat_has_moffset(insn->attr)) {
402 __get_moffset(insn);
403 goto done;
404 }
405
406 if (!inat_has_immediate(insn->attr))
407 /* no immediates */
408 goto done;
409
410 switch (inat_immediate_size(insn->attr)) {
411 case INAT_IMM_BYTE:
412 insn->immediate.value = get_next(char, insn);
413 insn->immediate.nbytes = 1;
414 break;
415 case INAT_IMM_WORD:
416 insn->immediate.value = get_next(short, insn);
417 insn->immediate.nbytes = 2;
418 break;
419 case INAT_IMM_DWORD:
420 insn->immediate.value = get_next(int, insn);
421 insn->immediate.nbytes = 4;
422 break;
423 case INAT_IMM_QWORD:
424 insn->immediate1.value = get_next(int, insn);
425 insn->immediate1.nbytes = 4;
426 insn->immediate2.value = get_next(int, insn);
427 insn->immediate2.nbytes = 4;
428 break;
429 case INAT_IMM_PTR:
430 __get_immptr(insn);
431 break;
432 case INAT_IMM_VWORD32:
433 __get_immv32(insn);
434 break;
435 case INAT_IMM_VWORD:
436 __get_immv(insn);
437 break;
438 default:
439 break;
440 }
441 if (inat_has_second_immediate(insn->attr)) {
442 insn->immediate2.value = get_next(char, insn);
443 insn->immediate2.nbytes = 1;
444 }
445done:
446 insn->immediate.got = 1;
447}
448
449/**
450 * insn_get_length() - Get the length of instruction
451 * @insn: &struct insn containing instruction
452 *
453 * If necessary, first collects the instruction up to and including the
454 * immediates bytes.
455 */
456void insn_get_length(struct insn *insn)
457{
458 if (insn->length)
459 return;
460 if (!insn->immediate.got)
461 insn_get_immediate(insn);
462 insn->length = (unsigned char)((unsigned long)insn->next_byte
463 - (unsigned long)insn->kaddr);
464}
diff --git a/arch/x86/lib/x86-opcode-map.txt b/arch/x86/lib/x86-opcode-map.txt
new file mode 100644
index 000000000000..083dd59dd74b
--- /dev/null
+++ b/arch/x86/lib/x86-opcode-map.txt
@@ -0,0 +1,719 @@
1# x86 Opcode Maps
2#
3#<Opcode maps>
4# Table: table-name
5# Referrer: escaped-name
6# opcode: mnemonic|GrpXXX [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
7# (or)
8# opcode: escape # escaped-name
9# EndTable
10#
11#<group maps>
12# GrpTable: GrpXXX
13# reg: mnemonic [operand1[,operand2...]] [(extra1)[,(extra2)...] [| 2nd-mnemonic ...]
14# EndTable
15#
16
17Table: one byte opcode
18Referrer:
19# 0x00 - 0x0f
2000: ADD Eb,Gb
2101: ADD Ev,Gv
2202: ADD Gb,Eb
2303: ADD Gv,Ev
2404: ADD AL,Ib
2505: ADD rAX,Iz
2606: PUSH ES (i64)
2707: POP ES (i64)
2808: OR Eb,Gb
2909: OR Ev,Gv
300a: OR Gb,Eb
310b: OR Gv,Ev
320c: OR AL,Ib
330d: OR rAX,Iz
340e: PUSH CS (i64)
350f: escape # 2-byte escape
36# 0x10 - 0x1f
3710: ADC Eb,Gb
3811: ADC Ev,Gv
3912: ADC Gb,Eb
4013: ADC Gv,Ev
4114: ADC AL,Ib
4215: ADC rAX,Iz
4316: PUSH SS (i64)
4417: POP SS (i64)
4518: SBB Eb,Gb
4619: SBB Ev,Gv
471a: SBB Gb,Eb
481b: SBB Gv,Ev
491c: SBB AL,Ib
501d: SBB rAX,Iz
511e: PUSH DS (i64)
521f: POP DS (i64)
53# 0x20 - 0x2f
5420: AND Eb,Gb
5521: AND Ev,Gv
5622: AND Gb,Eb
5723: AND Gv,Ev
5824: AND AL,Ib
5925: AND rAx,Iz
6026: SEG=ES (Prefix)
6127: DAA (i64)
6228: SUB Eb,Gb
6329: SUB Ev,Gv
642a: SUB Gb,Eb
652b: SUB Gv,Ev
662c: SUB AL,Ib
672d: SUB rAX,Iz
682e: SEG=CS (Prefix)
692f: DAS (i64)
70# 0x30 - 0x3f
7130: XOR Eb,Gb
7231: XOR Ev,Gv
7332: XOR Gb,Eb
7433: XOR Gv,Ev
7534: XOR AL,Ib
7635: XOR rAX,Iz
7736: SEG=SS (Prefix)
7837: AAA (i64)
7938: CMP Eb,Gb
8039: CMP Ev,Gv
813a: CMP Gb,Eb
823b: CMP Gv,Ev
833c: CMP AL,Ib
843d: CMP rAX,Iz
853e: SEG=DS (Prefix)
863f: AAS (i64)
87# 0x40 - 0x4f
8840: INC eAX (i64) | REX (o64)
8941: INC eCX (i64) | REX.B (o64)
9042: INC eDX (i64) | REX.X (o64)
9143: INC eBX (i64) | REX.XB (o64)
9244: INC eSP (i64) | REX.R (o64)
9345: INC eBP (i64) | REX.RB (o64)
9446: INC eSI (i64) | REX.RX (o64)
9547: INC eDI (i64) | REX.RXB (o64)
9648: DEC eAX (i64) | REX.W (o64)
9749: DEC eCX (i64) | REX.WB (o64)
984a: DEC eDX (i64) | REX.WX (o64)
994b: DEC eBX (i64) | REX.WXB (o64)
1004c: DEC eSP (i64) | REX.WR (o64)
1014d: DEC eBP (i64) | REX.WRB (o64)
1024e: DEC eSI (i64) | REX.WRX (o64)
1034f: DEC eDI (i64) | REX.WRXB (o64)
104# 0x50 - 0x5f
10550: PUSH rAX/r8 (d64)
10651: PUSH rCX/r9 (d64)
10752: PUSH rDX/r10 (d64)
10853: PUSH rBX/r11 (d64)
10954: PUSH rSP/r12 (d64)
11055: PUSH rBP/r13 (d64)
11156: PUSH rSI/r14 (d64)
11257: PUSH rDI/r15 (d64)
11358: POP rAX/r8 (d64)
11459: POP rCX/r9 (d64)
1155a: POP rDX/r10 (d64)
1165b: POP rBX/r11 (d64)
1175c: POP rSP/r12 (d64)
1185d: POP rBP/r13 (d64)
1195e: POP rSI/r14 (d64)
1205f: POP rDI/r15 (d64)
121# 0x60 - 0x6f
12260: PUSHA/PUSHAD (i64)
12361: POPA/POPAD (i64)
12462: BOUND Gv,Ma (i64)
12563: ARPL Ew,Gw (i64) | MOVSXD Gv,Ev (o64)
12664: SEG=FS (Prefix)
12765: SEG=GS (Prefix)
12866: Operand-Size (Prefix)
12967: Address-Size (Prefix)
13068: PUSH Iz (d64)
13169: IMUL Gv,Ev,Iz
1326a: PUSH Ib (d64)
1336b: IMUL Gv,Ev,Ib
1346c: INS/INSB Yb,DX
1356d: INS/INSW/INSD Yz,DX
1366e: OUTS/OUTSB DX,Xb
1376f: OUTS/OUTSW/OUTSD DX,Xz
138# 0x70 - 0x7f
13970: JO Jb
14071: JNO Jb
14172: JB/JNAE/JC Jb
14273: JNB/JAE/JNC Jb
14374: JZ/JE Jb
14475: JNZ/JNE Jb
14576: JBE/JNA Jb
14677: JNBE/JA Jb
14778: JS Jb
14879: JNS Jb
1497a: JP/JPE Jb
1507b: JNP/JPO Jb
1517c: JL/JNGE Jb
1527d: JNL/JGE Jb
1537e: JLE/JNG Jb
1547f: JNLE/JG Jb
155# 0x80 - 0x8f
15680: Grp1 Eb,Ib (1A)
15781: Grp1 Ev,Iz (1A)
15882: Grp1 Eb,Ib (1A),(i64)
15983: Grp1 Ev,Ib (1A)
16084: TEST Eb,Gb
16185: TEST Ev,Gv
16286: XCHG Eb,Gb
16387: XCHG Ev,Gv
16488: MOV Eb,Gb
16589: MOV Ev,Gv
1668a: MOV Gb,Eb
1678b: MOV Gv,Ev
1688c: MOV Ev,Sw
1698d: LEA Gv,M
1708e: MOV Sw,Ew
1718f: Grp1A (1A) | POP Ev (d64)
172# 0x90 - 0x9f
17390: NOP | PAUSE (F3) | XCHG r8,rAX
17491: XCHG rCX/r9,rAX
17592: XCHG rDX/r10,rAX
17693: XCHG rBX/r11,rAX
17794: XCHG rSP/r12,rAX
17895: XCHG rBP/r13,rAX
17996: XCHG rSI/r14,rAX
18097: XCHG rDI/r15,rAX
18198: CBW/CWDE/CDQE
18299: CWD/CDQ/CQO
1839a: CALLF Ap (i64)
1849b: FWAIT/WAIT
1859c: PUSHF/D/Q Fv (d64)
1869d: POPF/D/Q Fv (d64)
1879e: SAHF
1889f: LAHF
189# 0xa0 - 0xaf
190a0: MOV AL,Ob
191a1: MOV rAX,Ov
192a2: MOV Ob,AL
193a3: MOV Ov,rAX
194a4: MOVS/B Xb,Yb
195a5: MOVS/W/D/Q Xv,Yv
196a6: CMPS/B Xb,Yb
197a7: CMPS/W/D Xv,Yv
198a8: TEST AL,Ib
199a9: TEST rAX,Iz
200aa: STOS/B Yb,AL
201ab: STOS/W/D/Q Yv,rAX
202ac: LODS/B AL,Xb
203ad: LODS/W/D/Q rAX,Xv
204ae: SCAS/B AL,Yb
205af: SCAS/W/D/Q rAX,Xv
206# 0xb0 - 0xbf
207b0: MOV AL/R8L,Ib
208b1: MOV CL/R9L,Ib
209b2: MOV DL/R10L,Ib
210b3: MOV BL/R11L,Ib
211b4: MOV AH/R12L,Ib
212b5: MOV CH/R13L,Ib
213b6: MOV DH/R14L,Ib
214b7: MOV BH/R15L,Ib
215b8: MOV rAX/r8,Iv
216b9: MOV rCX/r9,Iv
217ba: MOV rDX/r10,Iv
218bb: MOV rBX/r11,Iv
219bc: MOV rSP/r12,Iv
220bd: MOV rBP/r13,Iv
221be: MOV rSI/r14,Iv
222bf: MOV rDI/r15,Iv
223# 0xc0 - 0xcf
224c0: Grp2 Eb,Ib (1A)
225c1: Grp2 Ev,Ib (1A)
226c2: RETN Iw (f64)
227c3: RETN
228c4: LES Gz,Mp (i64)
229c5: LDS Gz,Mp (i64)
230c6: Grp11 Eb,Ib (1A)
231c7: Grp11 Ev,Iz (1A)
232c8: ENTER Iw,Ib
233c9: LEAVE (d64)
234ca: RETF Iw
235cb: RETF
236cc: INT3
237cd: INT Ib
238ce: INTO (i64)
239cf: IRET/D/Q
240# 0xd0 - 0xdf
241d0: Grp2 Eb,1 (1A)
242d1: Grp2 Ev,1 (1A)
243d2: Grp2 Eb,CL (1A)
244d3: Grp2 Ev,CL (1A)
245d4: AAM Ib (i64)
246d5: AAD Ib (i64)
247d6:
248d7: XLAT/XLATB
249d8: ESC
250d9: ESC
251da: ESC
252db: ESC
253dc: ESC
254dd: ESC
255de: ESC
256df: ESC
257# 0xe0 - 0xef
258e0: LOOPNE/LOOPNZ Jb (f64)
259e1: LOOPE/LOOPZ Jb (f64)
260e2: LOOP Jb (f64)
261e3: JrCXZ Jb (f64)
262e4: IN AL,Ib
263e5: IN eAX,Ib
264e6: OUT Ib,AL
265e7: OUT Ib,eAX
266e8: CALL Jz (f64)
267e9: JMP-near Jz (f64)
268ea: JMP-far Ap (i64)
269eb: JMP-short Jb (f64)
270ec: IN AL,DX
271ed: IN eAX,DX
272ee: OUT DX,AL
273ef: OUT DX,eAX
274# 0xf0 - 0xff
275f0: LOCK (Prefix)
276f1:
277f2: REPNE (Prefix)
278f3: REP/REPE (Prefix)
279f4: HLT
280f5: CMC
281f6: Grp3_1 Eb (1A)
282f7: Grp3_2 Ev (1A)
283f8: CLC
284f9: STC
285fa: CLI
286fb: STI
287fc: CLD
288fd: STD
289fe: Grp4 (1A)
290ff: Grp5 (1A)
291EndTable
292
293Table: 2-byte opcode # First Byte is 0x0f
294Referrer: 2-byte escape
295# 0x0f 0x00-0x0f
29600: Grp6 (1A)
29701: Grp7 (1A)
29802: LAR Gv,Ew
29903: LSL Gv,Ew
30004:
30105: SYSCALL (o64)
30206: CLTS
30307: SYSRET (o64)
30408: INVD
30509: WBINVD
3060a:
3070b: UD2 (1B)
3080c:
3090d: NOP Ev
3100e:
3110f:
312# 0x0f 0x10-0x1f
31310:
31411:
31512:
31613:
31714:
31815:
31916:
32017:
32118: Grp16 (1A)
32219:
3231a:
3241b:
3251c:
3261d:
3271e:
3281f: NOP Ev
329# 0x0f 0x20-0x2f
33020: MOV Rd,Cd
33121: MOV Rd,Dd
33222: MOV Cd,Rd
33323: MOV Dd,Rd
33424:
33525:
33626:
33727:
33828: movaps Vps,Wps | movapd Vpd,Wpd (66)
33929: movaps Wps,Vps | movapd Wpd,Vpd (66)
3402a:
3412b:
3422c:
3432d:
3442e:
3452f:
346# 0x0f 0x30-0x3f
34730: WRMSR
34831: RDTSC
34932: RDMSR
35033: RDPMC
35134: SYSENTER
35235: SYSEXIT
35336:
35437: GETSEC
35538: escape # 3-byte escape 1
35639:
3573a: escape # 3-byte escape 2
3583b:
3593c:
3603d:
3613e:
3623f:
363# 0x0f 0x40-0x4f
36440: CMOVO Gv,Ev
36541: CMOVNO Gv,Ev
36642: CMOVB/C/NAE Gv,Ev
36743: CMOVAE/NB/NC Gv,Ev
36844: CMOVE/Z Gv,Ev
36945: CMOVNE/NZ Gv,Ev
37046: CMOVBE/NA Gv,Ev
37147: CMOVA/NBE Gv,Ev
37248: CMOVS Gv,Ev
37349: CMOVNS Gv,Ev
3744a: CMOVP/PE Gv,Ev
3754b: CMOVNP/PO Gv,Ev
3764c: CMOVL/NGE Gv,Ev
3774d: CMOVNL/GE Gv,Ev
3784e: CMOVLE/NG Gv,Ev
3794f: CMOVNLE/G Gv,Ev
380# 0x0f 0x50-0x5f
38150:
38251:
38352:
38453:
38554:
38655:
38756:
38857:
38958:
39059:
3915a:
3925b:
3935c:
3945d:
3955e:
3965f:
397# 0x0f 0x60-0x6f
39860:
39961:
40062:
40163:
40264:
40365:
40466:
40567:
40668:
40769:
4086a:
4096b:
4106c:
4116d:
4126e:
4136f:
414# 0x0f 0x70-0x7f
41570:
41671: Grp12 (1A)
41772: Grp13 (1A)
41873: Grp14 (1A)
41974:
42075:
42176:
42277:
42378: VMREAD Ed/q,Gd/q
42479: VMWRITE Gd/q,Ed/q
4257a:
4267b:
4277c:
4287d:
4297e:
4307f:
431# 0x0f 0x80-0x8f
43280: JO Jz (f64)
43381: JNO Jz (f64)
43482: JB/JNAE/JC Jz (f64)
43583: JNB/JAE/JNC Jz (f64)
43684: JZ/JE Jz (f64)
43785: JNZ/JNE Jz (f64)
43886: JBE/JNA Jz (f64)
43987: JNBE/JA Jz (f64)
44088: JS Jz (f64)
44189: JNS Jz (f64)
4428a: JP/JPE Jz (f64)
4438b: JNP/JPO Jz (f64)
4448c: JL/JNGE Jz (f64)
4458d: JNL/JGE Jz (f64)
4468e: JLE/JNG Jz (f64)
4478f: JNLE/JG Jz (f64)
448# 0x0f 0x90-0x9f
44990: SETO Eb
45091: SETNO Eb
45192: SETB/C/NAE Eb
45293: SETAE/NB/NC Eb
45394: SETE/Z Eb
45495: SETNE/NZ Eb
45596: SETBE/NA Eb
45697: SETA/NBE Eb
45798: SETS Eb
45899: SETNS Eb
4599a: SETP/PE Eb
4609b: SETNP/PO Eb
4619c: SETL/NGE Eb
4629d: SETNL/GE Eb
4639e: SETLE/NG Eb
4649f: SETNLE/G Eb
465# 0x0f 0xa0-0xaf
466a0: PUSH FS (d64)
467a1: POP FS (d64)
468a2: CPUID
469a3: BT Ev,Gv
470a4: SHLD Ev,Gv,Ib
471a5: SHLD Ev,Gv,CL
472a6:
473a7: GrpRNG
474a8: PUSH GS (d64)
475a9: POP GS (d64)
476aa: RSM
477ab: BTS Ev,Gv
478ac: SHRD Ev,Gv,Ib
479ad: SHRD Ev,Gv,CL
480ae: Grp15 (1A),(1C)
481af: IMUL Gv,Ev
482# 0x0f 0xb0-0xbf
483b0: CMPXCHG Eb,Gb
484b1: CMPXCHG Ev,Gv
485b2: LSS Gv,Mp
486b3: BTR Ev,Gv
487b4: LFS Gv,Mp
488b5: LGS Gv,Mp
489b6: MOVZX Gv,Eb
490b7: MOVZX Gv,Ew
491b8: JMPE | POPCNT Gv,Ev (F3)
492b9: Grp10 (1A)
493ba: Grp8 Ev,Ib (1A)
494bb: BTC Ev,Gv
495bc: BSF Gv,Ev
496bd: BSR Gv,Ev
497be: MOVSX Gv,Eb
498bf: MOVSX Gv,Ew
499# 0x0f 0xc0-0xcf
500c0: XADD Eb,Gb
501c1: XADD Ev,Gv
502c2:
503c3: movnti Md/q,Gd/q
504c4:
505c5:
506c6:
507c7: Grp9 (1A)
508c8: BSWAP RAX/EAX/R8/R8D
509c9: BSWAP RCX/ECX/R9/R9D
510ca: BSWAP RDX/EDX/R10/R10D
511cb: BSWAP RBX/EBX/R11/R11D
512cc: BSWAP RSP/ESP/R12/R12D
513cd: BSWAP RBP/EBP/R13/R13D
514ce: BSWAP RSI/ESI/R14/R14D
515cf: BSWAP RDI/EDI/R15/R15D
516# 0x0f 0xd0-0xdf
517d0:
518d1:
519d2:
520d3:
521d4:
522d5:
523d6:
524d7:
525d8:
526d9:
527da:
528db:
529dc:
530dd:
531de:
532df:
533# 0x0f 0xe0-0xef
534e0:
535e1:
536e2:
537e3:
538e4:
539e5:
540e6:
541e7:
542e8:
543e9:
544ea:
545eb:
546ec:
547ed:
548ee:
549ef:
550# 0x0f 0xf0-0xff
551f0:
552f1:
553f2:
554f3:
555f4:
556f5:
557f6:
558f7:
559f8:
560f9:
561fa:
562fb:
563fc:
564fd:
565fe:
566ff:
567EndTable
568
569Table: 3-byte opcode 1
570Referrer: 3-byte escape 1
57180: INVEPT Gd/q,Mdq (66)
57281: INVPID Gd/q,Mdq (66)
573f0: MOVBE Gv,Mv | CRC32 Gd,Eb (F2)
574f1: MOVBE Mv,Gv | CRC32 Gd,Ev (F2)
575EndTable
576
577Table: 3-byte opcode 2
578Referrer: 3-byte escape 2
579# all opcode is for SSE
580EndTable
581
582GrpTable: Grp1
5830: ADD
5841: OR
5852: ADC
5863: SBB
5874: AND
5885: SUB
5896: XOR
5907: CMP
591EndTable
592
593GrpTable: Grp1A
5940: POP
595EndTable
596
597GrpTable: Grp2
5980: ROL
5991: ROR
6002: RCL
6013: RCR
6024: SHL/SAL
6035: SHR
6046:
6057: SAR
606EndTable
607
608GrpTable: Grp3_1
6090: TEST Eb,Ib
6101:
6112: NOT Eb
6123: NEG Eb
6134: MUL AL,Eb
6145: IMUL AL,Eb
6156: DIV AL,Eb
6167: IDIV AL,Eb
617EndTable
618
619GrpTable: Grp3_2
6200: TEST Ev,Iz
6211:
6222: NOT Ev
6233: NEG Ev
6244: MUL rAX,Ev
6255: IMUL rAX,Ev
6266: DIV rAX,Ev
6277: IDIV rAX,Ev
628EndTable
629
630GrpTable: Grp4
6310: INC Eb
6321: DEC Eb
633EndTable
634
635GrpTable: Grp5
6360: INC Ev
6371: DEC Ev
6382: CALLN Ev (f64)
6393: CALLF Ep
6404: JMPN Ev (f64)
6415: JMPF Ep
6426: PUSH Ev (d64)
6437:
644EndTable
645
646GrpTable: Grp6
6470: SLDT Rv/Mw
6481: STR Rv/Mw
6492: LLDT Ew
6503: LTR Ew
6514: VERR Ew
6525: VERW Ew
653EndTable
654
655GrpTable: Grp7
6560: SGDT Ms | VMCALL (001),(11B) | VMLAUNCH (010),(11B) | VMRESUME (011),(11B) | VMXOFF (100),(11B)
6571: SIDT Ms | MONITOR (000),(11B) | MWAIT (001)
6582: LGDT Ms | XGETBV (000),(11B) | XSETBV (001),(11B)
6593: LIDT Ms
6604: SMSW Mw/Rv
6615:
6626: LMSW Ew
6637: INVLPG Mb | SWAPGS (o64),(000),(11B) | RDTSCP (001),(11B)
664EndTable
665
666GrpTable: Grp8
6674: BT
6685: BTS
6696: BTR
6707: BTC
671EndTable
672
673GrpTable: Grp9
6741: CMPXCHG8B/16B Mq/Mdq
6756: VMPTRLD Mq | VMCLEAR Mq (66) | VMXON Mq (F3)
6767: VMPTRST Mq
677EndTable
678
679GrpTable: Grp10
680EndTable
681
682GrpTable: Grp11
6830: MOV
684EndTable
685
686GrpTable: Grp12
687EndTable
688
689GrpTable: Grp13
690EndTable
691
692GrpTable: Grp14
693EndTable
694
695GrpTable: Grp15
6960: fxsave
6971: fxstor
6982: ldmxcsr
6993: stmxcsr
7004: XSAVE
7015: XRSTOR | lfence (11B)
7026: mfence (11B)
7037: clflush | sfence (11B)
704EndTable
705
706GrpTable: Grp16
7070: prefetch NTA
7081: prefetch T0
7092: prefetch T1
7103: prefetch T2
711EndTable
712
713GrpTable: GrpRNG
7140: xstore-rng
7151: xcrypt-ecb
7162: xcrypt-cbc
7174: xcrypt-cfb
7185: xcrypt-ofb
719EndTable