1
2
3
4
5
6 package x86asm
7
8 import (
9 "bytes"
10 "fmt"
11 )
12
13
14 type Inst struct {
15 Prefix Prefixes
16 Op Op
17 Opcode uint32
18 Args Args
19 Mode int
20 AddrSize int
21 DataSize int
22 MemBytes int
23 Len int
24 PCRel int
25 PCRelOff int
26
27 Broadcast bool
28 Zeroing bool
29 SAE bool
30 Rounding int8
31 }
32
33
34
35
36
37 type Prefixes [14]Prefix
38
39
40
41
42 type Prefix uint16
43
44 const (
45
46 PrefixImplicit Prefix = 0x8000
47 PrefixIgnored Prefix = 0x4000
48 PrefixInvalid Prefix = 0x2000
49
50
51 PrefixES Prefix = 0x26
52 PrefixCS Prefix = 0x2E
53 PrefixSS Prefix = 0x36
54 PrefixDS Prefix = 0x3E
55 PrefixFS Prefix = 0x64
56 PrefixGS Prefix = 0x65
57
58
59 PrefixPN Prefix = 0x12E
60 PrefixPT Prefix = 0x13E
61
62
63 PrefixDataSize Prefix = 0x66
64 PrefixData16 Prefix = 0x166
65 PrefixData32 Prefix = 0x266
66 PrefixAddrSize Prefix = 0x67
67 PrefixAddr16 Prefix = 0x167
68 PrefixAddr32 Prefix = 0x267
69
70
71 PrefixLOCK Prefix = 0xF0
72 PrefixREPN Prefix = 0xF2
73 PrefixXACQUIRE Prefix = 0x1F2
74 PrefixBND Prefix = 0x2F2
75 PrefixREP Prefix = 0xF3
76 PrefixXRELEASE Prefix = 0x1F3
77
78
79
80 PrefixREX Prefix = 0x40
81 PrefixREXW Prefix = 0x08
82 PrefixREXR Prefix = 0x04
83 PrefixREXX Prefix = 0x02
84 PrefixREXB Prefix = 0x01
85 PrefixVEX2Bytes Prefix = 0xC5
86 PrefixVEX3Bytes Prefix = 0xC4
87 PrefixEVEX Prefix = 0x62
88 )
89
90
91 func (p Prefix) IsREX() bool {
92 return p&0xF0 == PrefixREX
93 }
94
95 func (p Prefix) IsVEX() bool {
96 return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
97 }
98
99 func (p Prefix) IsEVEX() bool {
100 return p&0xFF == PrefixEVEX
101 }
102
103 func (p Prefix) String() string {
104 p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
105 if s := prefixNames[p]; s != "" {
106 return s
107 }
108
109 if p.IsREX() {
110 s := "REX."
111 if p&PrefixREXW != 0 {
112 s += "W"
113 }
114 if p&PrefixREXR != 0 {
115 s += "R"
116 }
117 if p&PrefixREXX != 0 {
118 s += "X"
119 }
120 if p&PrefixREXB != 0 {
121 s += "B"
122 }
123 return s
124 }
125
126 return fmt.Sprintf("Prefix(%#x)", int(p))
127 }
128
129
130 type Op uint32
131
132 func (op Op) String() string {
133 i := int(op)
134 if i < 0 || i >= len(opNames) || opNames[i] == "" {
135 if i < len(avxOpNames) && avxOpNames[i] != "" {
136 return avxOpNames[i]
137 }
138 return fmt.Sprintf("Op(%d)", i)
139 }
140 return opNames[i]
141 }
142
143
144
145
146 type Args [6]Arg
147
148
149
150 type Arg interface {
151 String() string
152 isArg()
153 }
154
155
156
157
158
159
160
161 type Reg uint8
162
163 const (
164 _ Reg = iota
165
166
167 AL
168 CL
169 DL
170 BL
171 AH
172 CH
173 DH
174 BH
175 SPB
176 BPB
177 SIB
178 DIB
179 R8B
180 R9B
181 R10B
182 R11B
183 R12B
184 R13B
185 R14B
186 R15B
187
188
189 AX
190 CX
191 DX
192 BX
193 SP
194 BP
195 SI
196 DI
197 R8W
198 R9W
199 R10W
200 R11W
201 R12W
202 R13W
203 R14W
204 R15W
205
206
207 EAX
208 ECX
209 EDX
210 EBX
211 ESP
212 EBP
213 ESI
214 EDI
215 R8L
216 R9L
217 R10L
218 R11L
219 R12L
220 R13L
221 R14L
222 R15L
223
224
225 RAX
226 RCX
227 RDX
228 RBX
229 RSP
230 RBP
231 RSI
232 RDI
233 R8
234 R9
235 R10
236 R11
237 R12
238 R13
239 R14
240 R15
241
242
243 IP
244 EIP
245 RIP
246
247
248 F0
249 F1
250 F2
251 F3
252 F4
253 F5
254 F6
255 F7
256
257
258 M0
259 M1
260 M2
261 M3
262 M4
263 M5
264 M6
265 M7
266
267
268 X0
269 X1
270 X2
271 X3
272 X4
273 X5
274 X6
275 X7
276 X8
277 X9
278 X10
279 X11
280 X12
281 X13
282 X14
283 X15
284 X16
285 X17
286 X18
287 X19
288 X20
289 X21
290 X22
291 X23
292 X24
293 X25
294 X26
295 X27
296 X28
297 X29
298 X30
299 X31
300
301
302 Y0
303 Y1
304 Y2
305 Y3
306 Y4
307 Y5
308 Y6
309 Y7
310 Y8
311 Y9
312 Y10
313 Y11
314 Y12
315 Y13
316 Y14
317 Y15
318 Y16
319 Y17
320 Y18
321 Y19
322 Y20
323 Y21
324 Y22
325 Y23
326 Y24
327 Y25
328 Y26
329 Y27
330 Y28
331 Y29
332 Y30
333 Y31
334
335
336 Z0
337 Z1
338 Z2
339 Z3
340 Z4
341 Z5
342 Z6
343 Z7
344 Z8
345 Z9
346 Z10
347 Z11
348 Z12
349 Z13
350 Z14
351 Z15
352 Z16
353 Z17
354 Z18
355 Z19
356 Z20
357 Z21
358 Z22
359 Z23
360 Z24
361 Z25
362 Z26
363 Z27
364 Z28
365 Z29
366 Z30
367 Z31
368
369
370 K0
371 K1
372 K2
373 K3
374 K4
375 K5
376 K6
377 K7
378
379
380 ES
381 CS
382 SS
383 DS
384 FS
385 GS
386
387
388 GDTR
389 IDTR
390 LDTR
391 MSW
392 TASK
393
394
395 CR0
396 CR1
397 CR2
398 CR3
399 CR4
400 CR5
401 CR6
402 CR7
403 CR8
404 CR9
405 CR10
406 CR11
407 CR12
408 CR13
409 CR14
410 CR15
411
412
413 DR0
414 DR1
415 DR2
416 DR3
417 DR4
418 DR5
419 DR6
420 DR7
421 DR8
422 DR9
423 DR10
424 DR11
425 DR12
426 DR13
427 DR14
428 DR15
429
430
431 TR0
432 TR1
433 TR2
434 TR3
435 TR4
436 TR5
437 TR6
438 TR7
439 )
440
441 const regMax = TR7
442
443 func (Reg) isArg() {}
444
445 func (r Reg) String() string {
446 i := int(r)
447 if i < 0 || i >= len(regNames) || regNames[i] == "" {
448 return fmt.Sprintf("Reg(%d)", i)
449 }
450 return regNames[i]
451 }
452
453
454
455 type Mem struct {
456 Segment Reg
457 Base Reg
458 Scale uint8
459 Index Reg
460 Disp int64
461 }
462
463 func (Mem) isArg() {}
464
465 func (m Mem) String() string {
466 var base, plus, scale, index, disp string
467
468 if m.Base != 0 {
469 base = m.Base.String()
470 }
471 if m.Scale != 0 {
472 if m.Base != 0 {
473 plus = "+"
474 }
475 if m.Scale > 1 {
476 scale = fmt.Sprintf("%d*", m.Scale)
477 }
478 index = m.Index.String()
479 }
480 if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
481 disp = fmt.Sprintf("%+#x", m.Disp)
482 }
483 return "[" + base + plus + scale + index + disp + "]"
484 }
485
486
487 type Rel int32
488
489 func (Rel) isArg() {}
490
491 func (r Rel) String() string {
492 return fmt.Sprintf(".%+d", r)
493 }
494
495
496 type Imm int64
497
498 func (Imm) isArg() {}
499
500 func (i Imm) String() string {
501 return fmt.Sprintf("%#x", int64(i))
502 }
503
504 func (i Inst) String() string {
505 var buf bytes.Buffer
506 for _, p := range i.Prefix {
507 if p == 0 {
508 break
509 }
510 if p&PrefixImplicit != 0 {
511 continue
512 }
513 fmt.Fprintf(&buf, "%v ", p)
514 }
515 fmt.Fprintf(&buf, "%v", i.Op)
516 sep := " "
517 for _, v := range i.Args {
518 if v == nil {
519 break
520 }
521 fmt.Fprintf(&buf, "%s%v", sep, v)
522 sep = ", "
523 }
524 return buf.String()
525 }
526
527 func isReg(a Arg) bool {
528 _, ok := a.(Reg)
529 return ok
530 }
531
532 func isSegReg(a Arg) bool {
533 r, ok := a.(Reg)
534 return ok && ES <= r && r <= GS
535 }
536
537 func isMem(a Arg) bool {
538 _, ok := a.(Mem)
539 return ok
540 }
541
542 func isImm(a Arg) bool {
543 _, ok := a.(Imm)
544 return ok
545 }
546
547 func regBytes(a Arg) int {
548 r, ok := a.(Reg)
549 if !ok {
550 return 0
551 }
552 if AL <= r && r <= R15B {
553 return 1
554 }
555 if AX <= r && r <= R15W {
556 return 2
557 }
558 if EAX <= r && r <= R15L {
559 return 4
560 }
561 if RAX <= r && r <= R15 {
562 return 8
563 }
564 return 0
565 }
566
567 func isSegment(p Prefix) bool {
568 switch p {
569 case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
570 return true
571 }
572 return false
573 }
574
575
576
577 var prefixNames = map[Prefix]string{
578 PrefixCS: "CS",
579 PrefixDS: "DS",
580 PrefixES: "ES",
581 PrefixFS: "FS",
582 PrefixGS: "GS",
583 PrefixSS: "SS",
584 PrefixLOCK: "LOCK",
585 PrefixREP: "REP",
586 PrefixREPN: "REPN",
587 PrefixAddrSize: "ADDRSIZE",
588 PrefixDataSize: "DATASIZE",
589 PrefixAddr16: "ADDR16",
590 PrefixData16: "DATA16",
591 PrefixAddr32: "ADDR32",
592 PrefixData32: "DATA32",
593 PrefixBND: "BND",
594 PrefixXACQUIRE: "XACQUIRE",
595 PrefixXRELEASE: "XRELEASE",
596 PrefixREX: "REX",
597 PrefixPT: "PT",
598 PrefixPN: "PN",
599 }
600
601 var regNames = [...]string{
602 AL: "AL",
603 CL: "CL",
604 BL: "BL",
605 DL: "DL",
606 AH: "AH",
607 CH: "CH",
608 BH: "BH",
609 DH: "DH",
610 SPB: "SPB",
611 BPB: "BPB",
612 SIB: "SIB",
613 DIB: "DIB",
614 R8B: "R8B",
615 R9B: "R9B",
616 R10B: "R10B",
617 R11B: "R11B",
618 R12B: "R12B",
619 R13B: "R13B",
620 R14B: "R14B",
621 R15B: "R15B",
622 AX: "AX",
623 CX: "CX",
624 BX: "BX",
625 DX: "DX",
626 SP: "SP",
627 BP: "BP",
628 SI: "SI",
629 DI: "DI",
630 R8W: "R8W",
631 R9W: "R9W",
632 R10W: "R10W",
633 R11W: "R11W",
634 R12W: "R12W",
635 R13W: "R13W",
636 R14W: "R14W",
637 R15W: "R15W",
638 EAX: "EAX",
639 ECX: "ECX",
640 EDX: "EDX",
641 EBX: "EBX",
642 ESP: "ESP",
643 EBP: "EBP",
644 ESI: "ESI",
645 EDI: "EDI",
646 R8L: "R8L",
647 R9L: "R9L",
648 R10L: "R10L",
649 R11L: "R11L",
650 R12L: "R12L",
651 R13L: "R13L",
652 R14L: "R14L",
653 R15L: "R15L",
654 RAX: "RAX",
655 RCX: "RCX",
656 RDX: "RDX",
657 RBX: "RBX",
658 RSP: "RSP",
659 RBP: "RBP",
660 RSI: "RSI",
661 RDI: "RDI",
662 R8: "R8",
663 R9: "R9",
664 R10: "R10",
665 R11: "R11",
666 R12: "R12",
667 R13: "R13",
668 R14: "R14",
669 R15: "R15",
670 IP: "IP",
671 EIP: "EIP",
672 RIP: "RIP",
673 F0: "F0",
674 F1: "F1",
675 F2: "F2",
676 F3: "F3",
677 F4: "F4",
678 F5: "F5",
679 F6: "F6",
680 F7: "F7",
681 M0: "M0",
682 M1: "M1",
683 M2: "M2",
684 M3: "M3",
685 M4: "M4",
686 M5: "M5",
687 M6: "M6",
688 M7: "M7",
689 X0: "X0",
690 X1: "X1",
691 X2: "X2",
692 X3: "X3",
693 X4: "X4",
694 X5: "X5",
695 X6: "X6",
696 X7: "X7",
697 X8: "X8",
698 X9: "X9",
699 X10: "X10",
700 X11: "X11",
701 X12: "X12",
702 X13: "X13",
703 X14: "X14",
704 X15: "X15",
705 X16: "X16",
706 X17: "X17",
707 X18: "X18",
708 X19: "X19",
709 X20: "X20",
710 X21: "X21",
711 X22: "X22",
712 X23: "X23",
713 X24: "X24",
714 X25: "X25",
715 X26: "X26",
716 X27: "X27",
717 X28: "X28",
718 X29: "X29",
719 X30: "X30",
720 X31: "X31",
721 Y0: "Y0",
722 Y1: "Y1",
723 Y2: "Y2",
724 Y3: "Y3",
725 Y4: "Y4",
726 Y5: "Y5",
727 Y6: "Y6",
728 Y7: "Y7",
729 Y8: "Y8",
730 Y9: "Y9",
731 Y10: "Y10",
732 Y11: "Y11",
733 Y12: "Y12",
734 Y13: "Y13",
735 Y14: "Y14",
736 Y15: "Y15",
737 Y16: "Y16",
738 Y17: "Y17",
739 Y18: "Y18",
740 Y19: "Y19",
741 Y20: "Y20",
742 Y21: "Y21",
743 Y22: "Y22",
744 Y23: "Y23",
745 Y24: "Y24",
746 Y25: "Y25",
747 Y26: "Y26",
748 Y27: "Y27",
749 Y28: "Y28",
750 Y29: "Y29",
751 Y30: "Y30",
752 Y31: "Y31",
753 Z0: "Z0",
754 Z1: "Z1",
755 Z2: "Z2",
756 Z3: "Z3",
757 Z4: "Z4",
758 Z5: "Z5",
759 Z6: "Z6",
760 Z7: "Z7",
761 Z8: "Z8",
762 Z9: "Z9",
763 Z10: "Z10",
764 Z11: "Z11",
765 Z12: "Z12",
766 Z13: "Z13",
767 Z14: "Z14",
768 Z15: "Z15",
769 Z16: "Z16",
770 Z17: "Z17",
771 Z18: "Z18",
772 Z19: "Z19",
773 Z20: "Z20",
774 Z21: "Z21",
775 Z22: "Z22",
776 Z23: "Z23",
777 Z24: "Z24",
778 Z25: "Z25",
779 Z26: "Z26",
780 Z27: "Z27",
781 Z28: "Z28",
782 Z29: "Z29",
783 Z30: "Z30",
784 Z31: "Z31",
785 K0: "K0",
786 K1: "K1",
787 K2: "K2",
788 K3: "K3",
789 K4: "K4",
790 K5: "K5",
791 K6: "K6",
792 K7: "K7",
793 CS: "CS",
794 SS: "SS",
795 DS: "DS",
796 ES: "ES",
797 FS: "FS",
798 GS: "GS",
799 GDTR: "GDTR",
800 IDTR: "IDTR",
801 LDTR: "LDTR",
802 MSW: "MSW",
803 TASK: "TASK",
804 CR0: "CR0",
805 CR1: "CR1",
806 CR2: "CR2",
807 CR3: "CR3",
808 CR4: "CR4",
809 CR5: "CR5",
810 CR6: "CR6",
811 CR7: "CR7",
812 CR8: "CR8",
813 CR9: "CR9",
814 CR10: "CR10",
815 CR11: "CR11",
816 CR12: "CR12",
817 CR13: "CR13",
818 CR14: "CR14",
819 CR15: "CR15",
820 DR0: "DR0",
821 DR1: "DR1",
822 DR2: "DR2",
823 DR3: "DR3",
824 DR4: "DR4",
825 DR5: "DR5",
826 DR6: "DR6",
827 DR7: "DR7",
828 DR8: "DR8",
829 DR9: "DR9",
830 DR10: "DR10",
831 DR11: "DR11",
832 DR12: "DR12",
833 DR13: "DR13",
834 DR14: "DR14",
835 DR15: "DR15",
836 TR0: "TR0",
837 TR1: "TR1",
838 TR2: "TR2",
839 TR3: "TR3",
840 TR4: "TR4",
841 TR5: "TR5",
842 TR6: "TR6",
843 TR7: "TR7",
844 }
845
View as plain text