about summary refs log tree commit diff stats
path: root/subx_opcodes
blob: 19fa1dbd9f6ceb25404203d0a72cc2dd3cb43bac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Opcodes currently supported by SubX:
  01: add r32 to rm32 (add)
  03: add rm32 to r32 (add)
  05: add imm32 to EAX (add)
  09: rm32 = bitwise OR of r32 with rm32 (or)
  0b: r32 = bitwise OR of r32 with rm32 (or)
  0d: EAX = bitwise OR of imm32 with EAX (or)
  21: rm32 = bitwise AND of r32 with rm32 (and)
  23: r32 = bitwise AND of r32 with rm32 (and)
  25: EAX = bitwise AND of imm32 with EAX (and)
  29: subtract r32 from rm32 (sub)
  2b: subtract rm32 from r32 (sub)
  2d: subtract imm32 from EAX (sub)
  31: rm32 = bitwise XOR of r32 with rm32 (xor)
  33: r32 = bitwise XOR of r32 with rm32 (xor)
  35: EAX = bitwise XOR of imm32 with EAX (xor)
  39: compare: set SF if rm32 < r32 (cmp)
  3b: compare: set SF if r32 < rm32 (cmp)
  3d: compare: set SF if EAX < imm32 (cmp)
  40: increment EAX (inc)
  41: increment ECX (inc)
  42: increment EDX (inc)
  43: increment EBX (inc)
  44: increment ESP (inc)
  45: increment EBP (inc)
  46: increment ESI (inc)
  47: increment EDI (inc)
  48: decrement EAX (dec)
  49: decrement ECX (dec)
  4a: decrement EDX (dec)
  4b: decrement EBX (dec)
  4c: decrement ESP (dec)
  4d: decrement EBP (dec)
  4e: decrement ESI (dec)
  4f: decrement EDI (dec)
  50: push EAX to stack (push)
  51: push ECX to stack (push)
  52: push EDX to stack (push)
  53: push EBX to stack (push)
  54: push ESP to stack (push)
  55: push EBP to stack (push)
  56: push ESI to stack (push)
  57: push EDI to stack (push)
  58: pop top of stack to EAX (pop)
  59: pop top of stack to ECX (pop)
  5a: pop top of stack to EDX (pop)
  5b: pop top of stack to EBX (pop)
  5c: pop top of stack to ESP (pop)
  5d: pop top of stack to EBP (pop)
  5e: pop top of stack to ESI (pop)
  5f: pop top of stack to EDI (pop)
  68: push imm32 to stack (push)
  69: multiply rm32 by imm32 and store result in r32 (imul)
  70: jump disp8 bytes away if OF is set (jcc/jo)
  71: jump disp8 bytes away if OF is unset (jcc/jno)
  72: jump disp8 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
  73: jump disp8 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
  74: jump disp8 bytes away if equal, if ZF is set (jcc/jz/je)
  75: jump disp8 bytes away if not equal, if ZF is not set (jcc/jnz/jne)
  76: jump disp8 bytes away if lesser or equal (addr, float), if ZF is set or CF is set (jcc/jbe/jna)
  77: jump disp8 bytes away if greater (addr, float), if ZF is unset and CF is unset (jcc/ja/jnbe)
  7c: jump disp8 bytes away if lesser, if SF != OF (jcc/jl/jnge)
  7d: jump disp8 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)
  7e: jump disp8 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)
  7f: jump disp8 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)
  81: combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)
  87: swap the contents of r32 and rm32 (xchg)
  88: copy r8 to r8/m8-at-r32
  89: copy r32 to rm32 (mov)
  8a: copy r8/m8-at-r32 to r8
  8b: copy rm32 to r32 (mov)
  8d: copy address in rm32 into r32 (lea)
  8f: pop top of stack to rm32 (pop)
  99: sign-extend EAX into EDX (cdq)
  b8: copy imm32 to EAX (mov)
  b9: copy imm32 to ECX (mov)
  ba: copy imm32 to EDX (mov)
  bb: copy imm32 to EBX (mov)
  bc: copy imm32 to ESP (mov)
  bd: copy imm32 to EBP (mov)
  be: copy imm32 to ESI (mov)
  bf: copy imm32 to EDI (mov)
  c1: shift rm32 by imm8 bits depending on subop (sal/sar/shl/shr)
  c3: return from most recent unfinished call (ret)
  c6: copy imm8 to r8/m8-at-r32 with subop 0 (mov)
  c7: copy imm32 to rm32 with subop 0 (mov)
  cd: software interrupt (int)
  d3: shift rm32 by CL bits depending on subop (sal/sar/shl/shr)
  e8: call disp32 (call)
  e9: jump disp32 bytes away (jmp)
  eb: jump disp8 bytes away (jmp)
  f4: halt (hlt)
  f7: negate/multiply/divide rm32 (with EAX and EDX if necessary) depending on subop (neg/mul/idiv)
  ff: increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)
  0f 2f: compare: set CF if x32 < xm32 (comiss)
  0f 80: jump disp32 bytes away if OF is set (jcc/jo)
  0f 81: jump disp32 bytes away if OF is unset (jcc/jno)
  0f 82: jump disp32 bytes away if lesser (addr, float), if CF is set (jcc/jb/jnae)
  0f 83: jump disp32 bytes away if greater or equal (addr, float), if CF is unset (jcc/jae/jnb)
  0f 84: jump disp32 bytes away if equal, if ZF is set (jcc/jz/je)
  0f 85: jump disp32 bytes away if not equal, if ZF is not set (jcc/jnz/jne)
  0f 86: jump disp32 bytes away if lesser or equal (addr, float), if ZF is set or CF is set (jcc/jbe/jna)
  0f 87: jump disp32 bytes away if greater (addr, float), if ZF is unset and CF is unset (jcc/ja/jnbe)
  0f 8c: jump disp32 bytes away if lesser, if SF != OF (jcc/jl/jnge)
  0f 8d: jump disp32 bytes away if greater or equal, if SF == OF (jcc/jge/jnl)
  0f 8e: jump disp32 bytes away if lesser or equal, if ZF is set or SF != OF (jcc/jle/jng)
  0f 8f: jump disp32 bytes away if greater, if ZF is unset and SF == OF (jcc/jg/jnle)
  0f 92: set r8/m8-at-rm32 to 1 if lesser (addr, float), if CF is set, 0 otherwise (setcc/setb/setnae)
  0f 93: set r8/m8-at-rm32 to 1 if greater or equal (addr, float), if CF is unset, 0 otherwise (setcc/setae/setnb)
  0f 94: set r8/m8-at-rm32 to 1 if equal, if ZF is set, 0 otherwise (setcc/setz/sete)
  0f 95: set r8/m8-at-rm32 to 1 if not equal, if ZF is not set, 0 otherwise (setcc/setnz/setne)
  0f 96: set r8/m8-at-rm32 to 1 if lesser or equal (addr, float), if ZF is set or CF is set, 0 otherwise (setcc/setbe/setna)
  0f 97: set r8/m8-at-rm32 to 1 if greater (addr, float), if ZF is unset and CF is unset, 0 otherwise (setcc/seta/setnbe)
  0f 9c: set r8/m8-at-rm32 to 1 if lesser, if SF != OF, 0 otherwise (setcc/setl/setnge)
  0f 9d: set r8/m8-at-rm32 to 1 if greater or equal, if SF == OF, 0 otherwise (setcc/setge/setnl)
  0f 9e: set r8/m8-at-rm32 to 1 if lesser or equal, if ZF is set or SF != OF, 0 otherwise (setcc/setle/setng)
  0f 9f: set r8/m8-at-rm32 to 1 if greater, if ZF is unset and SF == OF, 0 otherwise (setcc/setg/setnle)
  0f af: multiply rm32 into r32 (imul)
  f3 0f 10: copy xm32 to x32 (movss)
  f3 0f 11: copy x32 to xm32 (movss)
  f3 0f 2a: convert integer to floating-point (cvtsi2ss)
  f3 0f 2c: truncate floating-point to int (cvttss2si)
  f3 0f 2d: convert floating-point to int (cvtss2si)
  f3 0f 51: square root of float (sqrtss)
  f3 0f 52: inverse square root of float (rsqrtss)
  f3 0f 53: reciprocal of float (rcpss)
  f3 0f 58: add floats (addss)
  f3 0f 59: multiply floats (mulss)
  f3 0f 5c: subtract floats (subss)
  f3 0f 5d: minimum of two floats (minss)
  f3 0f 5e: divide floats (divss)
  f3 0f 5f: maximum of two floats (maxss)
Run `bootstrap help instructions` for details on words like 'r32' and 'disp8'.
For complete details on these instructions, consult the IA-32 manual (volume 2).
There's various versions of it online, such as https://c9x.me/x86.
The mnemonics in brackets will help you locate each instruction.