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
28
29
30
31
32 type Prefixes [14]Prefix
33
34
35
36
37 type Prefix uint16
38
39 const (
40
41 PrefixImplicit Prefix = 0x8000
42 PrefixIgnored Prefix = 0x4000
43 PrefixInvalid Prefix = 0x2000
44
45
46 PrefixES Prefix = 0x26
47 PrefixCS Prefix = 0x2E
48 PrefixSS Prefix = 0x36
49 PrefixDS Prefix = 0x3E
50 PrefixFS Prefix = 0x64
51 PrefixGS Prefix = 0x65
52
53
54 PrefixPN Prefix = 0x12E
55 PrefixPT Prefix = 0x13E
56
57
58 PrefixDataSize Prefix = 0x66
59 PrefixData16 Prefix = 0x166
60 PrefixData32 Prefix = 0x266
61 PrefixAddrSize Prefix = 0x67
62 PrefixAddr16 Prefix = 0x167
63 PrefixAddr32 Prefix = 0x267
64
65
66 PrefixLOCK Prefix = 0xF0
67 PrefixREPN Prefix = 0xF2
68 PrefixXACQUIRE Prefix = 0x1F2
69 PrefixBND Prefix = 0x2F2
70 PrefixREP Prefix = 0xF3
71 PrefixXRELEASE Prefix = 0x1F3
72
73
74
75 PrefixREX Prefix = 0x40
76 PrefixREXW Prefix = 0x08
77 PrefixREXR Prefix = 0x04
78 PrefixREXX Prefix = 0x02
79 PrefixREXB Prefix = 0x01
80 PrefixVEX2Bytes Prefix = 0xC5
81 PrefixVEX3Bytes Prefix = 0xC4
82 )
83
84
85 func (p Prefix) IsREX() bool {
86 return p&0xF0 == PrefixREX
87 }
88
89 func (p Prefix) IsVEX() bool {
90 return p&0xFF == PrefixVEX2Bytes || p&0xFF == PrefixVEX3Bytes
91 }
92
93 func (p Prefix) String() string {
94 p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
95 if s := prefixNames[p]; s != "" {
96 return s
97 }
98
99 if p.IsREX() {
100 s := "REX."
101 if p&PrefixREXW != 0 {
102 s += "W"
103 }
104 if p&PrefixREXR != 0 {
105 s += "R"
106 }
107 if p&PrefixREXX != 0 {
108 s += "X"
109 }
110 if p&PrefixREXB != 0 {
111 s += "B"
112 }
113 return s
114 }
115
116 return fmt.Sprintf("Prefix(%#x)", int(p))
117 }
118
119
120 type Op uint32
121
122 func (op Op) String() string {
123 i := int(op)
124 if i < 0 || i >= len(opNames) || opNames[i] == "" {
125 return fmt.Sprintf("Op(%d)", i)
126 }
127 return opNames[i]
128 }
129
130
131
132
133 type Args [4]Arg
134
135
136
137 type Arg interface {
138 String() string
139 isArg()
140 }
141
142
143
144
145
146
147
148 type Reg uint8
149
150 const (
151 _ Reg = iota
152
153
154 AL
155 CL
156 DL
157 BL
158 AH
159 CH
160 DH
161 BH
162 SPB
163 BPB
164 SIB
165 DIB
166 R8B
167 R9B
168 R10B
169 R11B
170 R12B
171 R13B
172 R14B
173 R15B
174
175
176 AX
177 CX
178 DX
179 BX
180 SP
181 BP
182 SI
183 DI
184 R8W
185 R9W
186 R10W
187 R11W
188 R12W
189 R13W
190 R14W
191 R15W
192
193
194 EAX
195 ECX
196 EDX
197 EBX
198 ESP
199 EBP
200 ESI
201 EDI
202 R8L
203 R9L
204 R10L
205 R11L
206 R12L
207 R13L
208 R14L
209 R15L
210
211
212 RAX
213 RCX
214 RDX
215 RBX
216 RSP
217 RBP
218 RSI
219 RDI
220 R8
221 R9
222 R10
223 R11
224 R12
225 R13
226 R14
227 R15
228
229
230 IP
231 EIP
232 RIP
233
234
235 F0
236 F1
237 F2
238 F3
239 F4
240 F5
241 F6
242 F7
243
244
245 M0
246 M1
247 M2
248 M3
249 M4
250 M5
251 M6
252 M7
253
254
255 X0
256 X1
257 X2
258 X3
259 X4
260 X5
261 X6
262 X7
263 X8
264 X9
265 X10
266 X11
267 X12
268 X13
269 X14
270 X15
271
272
273 ES
274 CS
275 SS
276 DS
277 FS
278 GS
279
280
281 GDTR
282 IDTR
283 LDTR
284 MSW
285 TASK
286
287
288 CR0
289 CR1
290 CR2
291 CR3
292 CR4
293 CR5
294 CR6
295 CR7
296 CR8
297 CR9
298 CR10
299 CR11
300 CR12
301 CR13
302 CR14
303 CR15
304
305
306 DR0
307 DR1
308 DR2
309 DR3
310 DR4
311 DR5
312 DR6
313 DR7
314 DR8
315 DR9
316 DR10
317 DR11
318 DR12
319 DR13
320 DR14
321 DR15
322
323
324 TR0
325 TR1
326 TR2
327 TR3
328 TR4
329 TR5
330 TR6
331 TR7
332 )
333
334 const regMax = TR7
335
336 func (Reg) isArg() {}
337
338 func (r Reg) String() string {
339 i := int(r)
340 if i < 0 || i >= len(regNames) || regNames[i] == "" {
341 return fmt.Sprintf("Reg(%d)", i)
342 }
343 return regNames[i]
344 }
345
346
347
348 type Mem struct {
349 Segment Reg
350 Base Reg
351 Scale uint8
352 Index Reg
353 Disp int64
354 }
355
356 func (Mem) isArg() {}
357
358 func (m Mem) String() string {
359 var base, plus, scale, index, disp string
360
361 if m.Base != 0 {
362 base = m.Base.String()
363 }
364 if m.Scale != 0 {
365 if m.Base != 0 {
366 plus = "+"
367 }
368 if m.Scale > 1 {
369 scale = fmt.Sprintf("%d*", m.Scale)
370 }
371 index = m.Index.String()
372 }
373 if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
374 disp = fmt.Sprintf("%+#x", m.Disp)
375 }
376 return "[" + base + plus + scale + index + disp + "]"
377 }
378
379
380 type Rel int32
381
382 func (Rel) isArg() {}
383
384 func (r Rel) String() string {
385 return fmt.Sprintf(".%+d", r)
386 }
387
388
389 type Imm int64
390
391 func (Imm) isArg() {}
392
393 func (i Imm) String() string {
394 return fmt.Sprintf("%#x", int64(i))
395 }
396
397 func (i Inst) String() string {
398 var buf bytes.Buffer
399 for _, p := range i.Prefix {
400 if p == 0 {
401 break
402 }
403 if p&PrefixImplicit != 0 {
404 continue
405 }
406 fmt.Fprintf(&buf, "%v ", p)
407 }
408 fmt.Fprintf(&buf, "%v", i.Op)
409 sep := " "
410 for _, v := range i.Args {
411 if v == nil {
412 break
413 }
414 fmt.Fprintf(&buf, "%s%v", sep, v)
415 sep = ", "
416 }
417 return buf.String()
418 }
419
420 func isReg(a Arg) bool {
421 _, ok := a.(Reg)
422 return ok
423 }
424
425 func isSegReg(a Arg) bool {
426 r, ok := a.(Reg)
427 return ok && ES <= r && r <= GS
428 }
429
430 func isMem(a Arg) bool {
431 _, ok := a.(Mem)
432 return ok
433 }
434
435 func isImm(a Arg) bool {
436 _, ok := a.(Imm)
437 return ok
438 }
439
440 func regBytes(a Arg) int {
441 r, ok := a.(Reg)
442 if !ok {
443 return 0
444 }
445 if AL <= r && r <= R15B {
446 return 1
447 }
448 if AX <= r && r <= R15W {
449 return 2
450 }
451 if EAX <= r && r <= R15L {
452 return 4
453 }
454 if RAX <= r && r <= R15 {
455 return 8
456 }
457 return 0
458 }
459
460 func isSegment(p Prefix) bool {
461 switch p {
462 case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
463 return true
464 }
465 return false
466 }
467
468
469
470 var prefixNames = map[Prefix]string{
471 PrefixCS: "CS",
472 PrefixDS: "DS",
473 PrefixES: "ES",
474 PrefixFS: "FS",
475 PrefixGS: "GS",
476 PrefixSS: "SS",
477 PrefixLOCK: "LOCK",
478 PrefixREP: "REP",
479 PrefixREPN: "REPN",
480 PrefixAddrSize: "ADDRSIZE",
481 PrefixDataSize: "DATASIZE",
482 PrefixAddr16: "ADDR16",
483 PrefixData16: "DATA16",
484 PrefixAddr32: "ADDR32",
485 PrefixData32: "DATA32",
486 PrefixBND: "BND",
487 PrefixXACQUIRE: "XACQUIRE",
488 PrefixXRELEASE: "XRELEASE",
489 PrefixREX: "REX",
490 PrefixPT: "PT",
491 PrefixPN: "PN",
492 }
493
494 var regNames = [...]string{
495 AL: "AL",
496 CL: "CL",
497 BL: "BL",
498 DL: "DL",
499 AH: "AH",
500 CH: "CH",
501 BH: "BH",
502 DH: "DH",
503 SPB: "SPB",
504 BPB: "BPB",
505 SIB: "SIB",
506 DIB: "DIB",
507 R8B: "R8B",
508 R9B: "R9B",
509 R10B: "R10B",
510 R11B: "R11B",
511 R12B: "R12B",
512 R13B: "R13B",
513 R14B: "R14B",
514 R15B: "R15B",
515 AX: "AX",
516 CX: "CX",
517 BX: "BX",
518 DX: "DX",
519 SP: "SP",
520 BP: "BP",
521 SI: "SI",
522 DI: "DI",
523 R8W: "R8W",
524 R9W: "R9W",
525 R10W: "R10W",
526 R11W: "R11W",
527 R12W: "R12W",
528 R13W: "R13W",
529 R14W: "R14W",
530 R15W: "R15W",
531 EAX: "EAX",
532 ECX: "ECX",
533 EDX: "EDX",
534 EBX: "EBX",
535 ESP: "ESP",
536 EBP: "EBP",
537 ESI: "ESI",
538 EDI: "EDI",
539 R8L: "R8L",
540 R9L: "R9L",
541 R10L: "R10L",
542 R11L: "R11L",
543 R12L: "R12L",
544 R13L: "R13L",
545 R14L: "R14L",
546 R15L: "R15L",
547 RAX: "RAX",
548 RCX: "RCX",
549 RDX: "RDX",
550 RBX: "RBX",
551 RSP: "RSP",
552 RBP: "RBP",
553 RSI: "RSI",
554 RDI: "RDI",
555 R8: "R8",
556 R9: "R9",
557 R10: "R10",
558 R11: "R11",
559 R12: "R12",
560 R13: "R13",
561 R14: "R14",
562 R15: "R15",
563 IP: "IP",
564 EIP: "EIP",
565 RIP: "RIP",
566 F0: "F0",
567 F1: "F1",
568 F2: "F2",
569 F3: "F3",
570 F4: "F4",
571 F5: "F5",
572 F6: "F6",
573 F7: "F7",
574 M0: "M0",
575 M1: "M1",
576 M2: "M2",
577 M3: "M3",
578 M4: "M4",
579 M5: "M5",
580 M6: "M6",
581 M7: "M7",
582 X0: "X0",
583 X1: "X1",
584 X2: "X2",
585 X3: "X3",
586 X4: "X4",
587 X5: "X5",
588 X6: "X6",
589 X7: "X7",
590 X8: "X8",
591 X9: "X9",
592 X10: "X10",
593 X11: "X11",
594 X12: "X12",
595 X13: "X13",
596 X14: "X14",
597 X15: "X15",
598 CS: "CS",
599 SS: "SS",
600 DS: "DS",
601 ES: "ES",
602 FS: "FS",
603 GS: "GS",
604 GDTR: "GDTR",
605 IDTR: "IDTR",
606 LDTR: "LDTR",
607 MSW: "MSW",
608 TASK: "TASK",
609 CR0: "CR0",
610 CR1: "CR1",
611 CR2: "CR2",
612 CR3: "CR3",
613 CR4: "CR4",
614 CR5: "CR5",
615 CR6: "CR6",
616 CR7: "CR7",
617 CR8: "CR8",
618 CR9: "CR9",
619 CR10: "CR10",
620 CR11: "CR11",
621 CR12: "CR12",
622 CR13: "CR13",
623 CR14: "CR14",
624 CR15: "CR15",
625 DR0: "DR0",
626 DR1: "DR1",
627 DR2: "DR2",
628 DR3: "DR3",
629 DR4: "DR4",
630 DR5: "DR5",
631 DR6: "DR6",
632 DR7: "DR7",
633 DR8: "DR8",
634 DR9: "DR9",
635 DR10: "DR10",
636 DR11: "DR11",
637 DR12: "DR12",
638 DR13: "DR13",
639 DR14: "DR14",
640 DR15: "DR15",
641 TR0: "TR0",
642 TR1: "TR1",
643 TR2: "TR2",
644 TR3: "TR3",
645 TR4: "TR4",
646 TR5: "TR5",
647 TR6: "TR6",
648 TR7: "TR7",
649 }
650
View as plain text