Rizin
unix-like reverse engineering framework and cli tools
8051_ops.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Florian Märkl <info@florianmaerkl.de>
2 // SPDX-FileCopyrightText: 2015-2016 pancake <pancake@nopcode.org>
3 // SPDX-FileCopyrightText: 2015-2016 condret <condr3t@protonmail.com>
4 // SPDX-FileCopyrightText: 2015-2016 riq <ricardoquesada@gmail.com>
5 // SPDX-FileCopyrightText: 2015-2016 qnix <qnix@0x80.org>
6 // SPDX-License-Identifier: LGPL-3.0-only
7 
8 #ifndef _8051_OPS_H
9 #define _8051_OPS_H
10 
11 #include <rz_types.h>
12 
14 static inline ut64 apply_bank(ut64 ref, ut16 addr) {
15  return (ref & ~0xffff) | (ut64)addr;
16 }
17 
18 static inline ut64 arg_offset(ut64 bank, ut16 pc, ut8 offset) {
19  if (offset < 0x80) {
20  return apply_bank(bank, pc + offset);
21  }
22  offset = 0 - offset;
23  return apply_bank(bank, pc - offset);
24 }
25 
26 static inline ut64 arg_addr11(ut64 bank, ut16 pc, const ut8 *buf) {
27  // ADDR11 is replacing lower 11 bits of (pre-incremented) PC
28  return apply_bank(bank, (pc & 0xf800) + ((buf[0] & 0xe0) << 3) + buf[1]);
29 }
30 
31 static inline ut8 arg_bit(ut8 bit_addr) {
32  if (bit_addr < 0x80) {
33  // bit addresses 0x00-0x7f are mapped to bytes at 0x20-0x2f
34  return (bit_addr >> 3) + 0x20;
35  }
36  // bit addresses 0x80-0xff are mapped to bytes at 0x80, 0x88, 0x98, ...
37  return bit_addr & 0xf8;
38 }
39 
40 typedef enum {
77  OP_XRL
79 
80 typedef enum {
81  A_NONE = 0,
82  A_RI, // @Ri
83  A_RN, // Rn
90  A_OFFSET
92 
93 typedef enum {
94  M_NONE = 0,
95  M_RI = 0x01,
96  M_RN = 0x07,
97  M_ADDR11 = 0xe0
99 
100 typedef struct {
102  int cycles;
103  op8051 instr; // instruction
105  char *string; // disassembly output
106  size_t len;
107  argmask8051 mask; // bits masked to determine opcode
111 } _8051_op_t;
112 
113 static _8051_op_t _8051_ops[] = {
114 #define T(op) RZ_ANALYSIS_OP_TYPE_##op
115  { 0x00, 1, OP_NOP, T(NOP), "nop", 1, M_NONE, 0, 0, 0 },
116  { 0x01, 2, OP_JMP, T(JMP), "ajmp 0x%04x", 2, M_ADDR11, A_ADDR11, 0, 0 },
117  { 0x02, 2, OP_JMP, T(JMP), "ljmp 0x%04x", 3, M_NONE, A_ADDR16, 0, 0 },
118  { 0x03, 1, OP_RR, T(ROR), "rr a", 1, M_NONE, 0, 0, 0 },
119  { 0x04, 1, OP_INC, T(ADD), "inc a", 1, M_NONE, 0, 0, 0 },
120  { 0x05, 1, OP_INC, T(ADD), "inc 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
121  { 0x06, 1, OP_INC, T(ADD), "inc @r%d", 1, M_RI, A_RI, 0, 0 },
122  { 0x08, 1, OP_INC, T(ADD), "inc r%d", 1, M_RN, A_RN, 0, 0 },
123  { 0x10, 2, OP_JBC, T(CJMP), "jbc 0x%02x.%d, 0x%04x", 3, M_NONE, A_BIT, A_OFFSET, 0 },
124  { 0x11, 2, OP_CALL, T(CALL), "acall 0x%04x", 2, M_ADDR11, A_ADDR11, 0, 0 },
125  { 0x12, 2, OP_CALL, T(CALL), "lcall 0x%04x", 3, M_NONE, A_ADDR16, 0, 0 },
126  { 0x13, 1, OP_RRC, T(ROR), "rrc a", 1, M_NONE, 0, 0, 0 },
127  { 0x14, 1, OP_DEC, T(SUB), "dec a", 1, M_NONE, 0, 0, 0 },
128  { 0x15, 1, OP_DEC, T(SUB), "dec 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
129  {
130  0x16,
131  1,
132  OP_DEC,
133  T(SUB),
134  "dec @r%d",
135  1,
136  M_RI,
137  A_RI,
138  0,
139  0,
140  },
141  { 0x18, 1, OP_DEC, T(SUB), "dec r%d", 1, M_RN, A_RN, 0, 0 },
142  { 0x20, 2, OP_JB, T(CJMP), "jb 0x%02x.%d, 0x%04x", 3, M_NONE, A_BIT, A_OFFSET, 0 },
143  { 0x22, 2, OP_RET, T(RET), "ret", 1, M_NONE, A_NONE, 0, 0 },
144  { 0x23, 1, OP_RL, T(ROL), "rl a", 1, M_NONE, A_NONE, 0, 0 },
145  { 0x24, 1, OP_ADD, T(ADD), "add a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
146  { 0x25, 1, OP_ADD, T(ADD), "add a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
147  { 0x26, 1, OP_ADD, T(ADD), "add a, @r%d", 1, M_RI, A_RI, 0, 0 },
148  { 0x28, 1, OP_ADD, T(ADD), "add a, r%d", 1, M_RN, A_RN, 0, 0 },
149  { 0x30, 2, OP_JNB, T(CJMP), "jnb 0x%02x.%d, 0x%04x", 3, M_NONE, A_BIT, A_OFFSET, 0 },
150  { 0x32, 2, OP_RET, T(RET), "reti", 1, M_NONE, 0, 0, 0 },
151  { 0x33, 1, OP_RLC, T(ROR), "rlc a", 1, M_NONE, 0, 0, 0 },
152  { 0x34, 1, OP_ADDC, T(ADD), "addc a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
153  { 0x35, 1, OP_ADDC, T(ADD), "addc a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
154  { 0x36, 1, OP_ADDC, T(ADD), "addc a, @r%d", 1, M_RI, A_RI, 0, 0 },
155  { 0x38, 1, OP_ADDC, T(ADD), "addc a, r%d", 1, M_RN, A_RN, 0, 0 },
156  { 0x40, 2, OP_JC, T(CJMP), "jc 0x%04x", 2, M_NONE, A_OFFSET, 0, 0 },
157  { 0x42, 1, OP_ORL, T(OR), "orl 0x%02x, a", 2, M_NONE, A_DIRECT, 0, 0 },
158  { 0x43, 1, OP_ORL, T(OR), "orl 0x%02x, #0x%02x", 3, M_NONE, A_DIRECT, A_IMMEDIATE, 0 },
159  { 0x44, 1, OP_ORL, T(OR), "orl a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
160  { 0x45, 1, OP_ORL, T(OR), "orl a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
161  { 0x46, 1, OP_ORL, T(OR), "orl a, @r%d", 1, M_RI, A_RI, 0, 0 },
162  { 0x48, 1, OP_ORL, T(OR), "orl a, r%d", 1, M_RN, A_RN, 0, 0 },
163  { 0x50, 2, OP_JNC, T(CJMP), "jnc 0x%04x", 2, M_NONE, A_OFFSET, 0, 0 },
164  { 0x52, 1, OP_ANL, T(AND), "anl 0x%02x, a", 2, M_NONE, A_DIRECT, 0, 0 },
165  { 0x53, 2, OP_ANL, T(AND), "anl 0x%02x, #0x%02x", 3, M_NONE, A_DIRECT, A_IMMEDIATE, 0 },
166  { 0x54, 1, OP_ANL, T(AND), "anl a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
167  { 0x55, 1, OP_ANL, T(AND), "anl a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
168  { 0x56, 1, OP_ANL, T(AND), "anl a, @r%d", 1, M_RI, A_RI, 0, 0 },
169  { 0x58, 1, OP_ANL, T(AND), "anl a, r%d", 1, M_RN, A_RN, 0, 0 },
170  { 0x60, 2, OP_JZ, T(CJMP), "jz 0x%04x", 2, M_NONE, A_OFFSET, 0, 0 },
171  { 0x62, 1, OP_XRL, T(XOR), "xrl 0x%02x, a", 2, M_NONE, A_DIRECT, 0, 0 },
172  { 0x63, 2, OP_XRL, T(XOR), "xrl 0x%02x, #0x%02x", 3, M_NONE, A_DIRECT, A_IMMEDIATE, 0 },
173  { 0x64, 1, OP_XRL, T(XOR), "xrl a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
174  { 0x65, 1, OP_XRL, T(XOR), "xrl a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
175  { 0x66, 1, OP_XRL, T(XOR), "xrl a, @r%d", 1, M_RI, A_RI, 0, 0 },
176  { 0x68, 1, OP_XRL, T(XOR), "xrl a, r%d", 1, M_RN, A_RN, 0, 0 },
177  { 0x70, 2, OP_JNZ, T(CJMP), "jnz 0x%04x", 2, M_NONE, A_OFFSET, 0, 0 },
178  { 0x72, 2, OP_ORL, T(OR), "orl c, 0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
179  { 0x73, 2, OP_JMP, T(UJMP), "jmp @a+dptr", 1, M_NONE, 0, 0, 0 },
180  { 0x74, 1, OP_MOV, T(MOV), "mov a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
181  { 0x75, 2, OP_MOV, T(MOV), "mov 0x%02x, #0x%02x", 3, M_NONE, A_DIRECT, A_IMMEDIATE, 0 },
182  { 0x76, 1, OP_MOV, T(MOV), "mov @r%d, #0x%02x", 2, M_RI, A_RI, A_IMMEDIATE, 0 },
183  { 0x78, 1, OP_MOV, T(MOV), "mov r%d, #0x%02x", 2, M_RN, A_RN, A_IMMEDIATE, 0 },
184  { 0x80, 2, OP_JMP, T(JMP), "sjmp 0x%04x", 2, M_NONE, A_OFFSET, 0, 0 },
185  { 0x82, 2, OP_ANL, T(AND), "anl c, 0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
186  { 0x83, 2, OP_MOV, T(MOV), "movc a, @a+pc", 1, M_NONE, 0, 0, 0 },
187  { 0x84, 4, OP_DIV, T(DIV), "div ab", 1, M_NONE, 0, 0, 0 },
188  { 0x85, 2, OP_MOV, T(MOV), "mov 0x%02x, 0x%02x", 3, M_NONE, A_DIRECT, A_DIRECT, 0 },
189  { 0x86, 2, OP_MOV, T(MOV), "mov 0x%02x, @r%d", 2, M_RI, A_DIRECT, A_RI, 0 },
190  { 0x88, 2, OP_MOV, T(MOV), "mov 0x%02x, r%d", 2, M_RN, A_DIRECT, A_RN, 0 },
191  { 0x90, 2, OP_MOV, T(MOV), "mov dptr, #0x%04x", 3, M_NONE, A_IMM16, 0, 0 },
192  { 0x92, 2, OP_MOV, T(MOV), "mov 0x%02x.%d, c", 2, M_NONE, A_BIT, 0, 0 },
193  { 0x93, 2, OP_MOV, T(MOV), "movc a, @a+dptr", 1, M_NONE, 0, 0, 0 },
194  { 0x94, 1, OP_SUBB, T(SUB), "subb a, #0x%02x", 2, M_NONE, A_IMMEDIATE, 0, 0 },
195  { 0x95, 1, OP_SUBB, T(SUB), "subb a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
196  { 0x96, 1, OP_SUBB, T(SUB), "subb a, @r%d", 1, M_RI, A_RI, 0, 0 },
197  { 0x98, 1, OP_SUBB, T(SUB), "subb a, r%d", 1, M_RN, A_RN, 0, 0 },
198  { 0xa0, 2, OP_ORL, T(OR), "orl c, /0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
199  { 0xa2, 1, OP_MOV, T(MOV), "mov c, 0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
200  { 0xa3, 2, OP_INC, T(ADD), "inc dptr", 1, M_NONE, 0, 0, 0 },
201  { 0xa4, 4, OP_MUL, T(MUL), "mul ab", 1, M_NONE, 0, 0, 0 },
202  { 0xa6, 2, OP_MOV, T(MOV), "mov @r%d, 0x%02x", 2, M_RI, A_RI, A_DIRECT, 0 },
203  { 0xa8, 2, OP_MOV, T(MOV), "mov r%d, 0x%02x", 2, M_RN, A_RN, A_DIRECT, 0 },
204  { 0xb0, 2, OP_ANL, T(AND), "anl c, /0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
205  { 0xb2, 1, OP_CPL, T(CPL), "cpl 0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
206  { 0xb3, 1, OP_CPL, T(CPL), "cpl c", 1, M_NONE, 0, 0 },
207  { 0xb4, 2, OP_CJNE, T(CJMP), "cjne a, #0x%02x, 0x%04x", 3, M_NONE, A_IMMEDIATE, A_OFFSET, 0 },
208  { 0xb5, 2, OP_CJNE, T(CJMP), "cjne a, 0x%02x, 0x%04x", 3, M_NONE, A_DIRECT, A_OFFSET, 0 },
209  { 0xb6, 2, OP_CJNE, T(CJMP) | T(IND), "cjne @r%d, #0x%02x, 0x%04x", 3, M_RI, A_RI, A_IMMEDIATE, A_OFFSET },
210  { 0xb8, 2, OP_CJNE, T(CJMP), "cjne r%d, #0x%02x, 0x%04x", 3, M_RN, A_RN, A_IMMEDIATE, A_OFFSET },
211  { 0xc0, 2, OP_PUSH, T(PUSH) | T(MEM), "push 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
212  { 0xc2, 1, OP_CLR, T(IO), "clr 0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
213  { 0xc3, 1, OP_CLR, T(IO), "clr c", 1, M_NONE, 0, 0, 0 },
214  { 0xc4, 1, OP_SWAP, T(XCHG), "swap a", 1, M_NONE, 0, 0, 0 },
215  { 0xc5, 1, OP_XCH, T(XCHG), "xch a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
216  { 0xc6, 1, OP_XCH, T(XCHG), "xch a, @r%d", 1, M_RI, A_RI, 0, 0 },
217  { 0xc8, 1, OP_XCH, T(XCHG), "xch a, r%d", 1, M_RN, A_RN, 0, 0 },
218  { 0xd0, 2, OP_POP, T(POP) | T(MEM), "pop 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
219  { 0xd2, 1, OP_SETB, T(IO), "setb 0x%02x.%d", 2, M_NONE, A_BIT, 0, 0 },
220  { 0xd3, 1, OP_SETB, T(IO), "setb c", 1, M_NONE, 0, 0, 0 },
221  { 0xd4, 1, OP_DA, T(CAST), "da a", 1, M_NONE, 0, 0, 0 },
222  { 0xd5, 2, OP_DJNZ, T(CJMP), "djnz 0x%02x, 0x%04x", 3, M_NONE, A_DIRECT, A_OFFSET, 0 },
223  { 0xd6, 1, OP_XCH, T(XCHG), "xchd a, @r%d", 1, M_RI, A_RI, 0, 0 },
224  { 0xd8, 2, OP_DJNZ, T(CJMP), "djnz r%d, 0x%04x", 2, M_RN, A_RN, A_OFFSET, 0 },
225  { 0xe0, 2, OP_MOV, T(MOV), "movx a, @dptr", 1, M_NONE, 0, 0, 0 },
226  { 0xe2, 2, OP_MOV, T(MOV), "movx a, @r%d", 1, M_RI, A_RI, 0, 0 },
227  { 0xe4, 1, OP_CLR, T(IO), "clr a", 1, M_NONE, 0, 0, 0 },
228  { 0xe5, 1, OP_MOV, T(MOV), "mov a, 0x%02x", 2, M_NONE, A_DIRECT, 0, 0 },
229  { 0xe6, 1, OP_MOV, T(MOV), "mov a, @r%d", 1, M_RI, A_RI, 0, 0 },
230  { 0xe8, 1, OP_MOV, T(MOV), "mov a, r%d", 1, M_RN, A_RN, 0, 0 },
231  { 0xf0, 2, OP_MOV, T(MOV), "movx @dptr, a", 1, M_NONE, 0, 0, 0 },
232  { 0xf2, 2, OP_MOV, T(MOV), "movx @r%d, a", 1, M_RI, A_RI, 0, 0 },
233  { 0xf4, 1, OP_CPL, T(CPL), "cpl a", 1, M_NONE, 0, 0, 0 },
234  { 0xf5, 1, OP_MOV, T(MOV), "mov 0x%02x, a", 2, M_NONE, A_DIRECT, 0, 0 },
235  { 0xf6, 1, OP_MOV, T(MOV), "mov @r%d, a", 1, M_RI, A_RI, 0, 0 },
236  { 0xf8, 1, OP_MOV, T(MOV), "mov r%d, a", 1, M_RN, A_RN, 0, 0 },
237  { 0xff, 1, OP_INVALID, T(ILL), NULL, 0, 0, 0 }
238 #undef T
239 };
240 
241 #endif
#define T(op)
argtype8051
Definition: 8051_ops.h:80
@ A_ADDR11
Definition: 8051_ops.h:84
@ A_IMMEDIATE
Definition: 8051_ops.h:88
@ A_NONE
Definition: 8051_ops.h:81
@ A_DIRECT
Definition: 8051_ops.h:86
@ A_RN
Definition: 8051_ops.h:83
@ A_BIT
Definition: 8051_ops.h:87
@ A_OFFSET
Definition: 8051_ops.h:90
@ A_RI
Definition: 8051_ops.h:82
@ A_ADDR16
Definition: 8051_ops.h:85
@ A_IMM16
Definition: 8051_ops.h:89
static ut64 arg_offset(ut64 bank, ut16 pc, ut8 offset)
Definition: 8051_ops.h:18
static ut64 arg_addr11(ut64 bank, ut16 pc, const ut8 *buf)
Definition: 8051_ops.h:26
static ut64 apply_bank(ut64 ref, ut16 addr)
Construct an address with the higher bits from ref (determining the bank) and the lower from addr (of...
Definition: 8051_ops.h:14
argmask8051
Definition: 8051_ops.h:93
@ M_RI
Definition: 8051_ops.h:95
@ M_RN
Definition: 8051_ops.h:96
@ M_ADDR11
Definition: 8051_ops.h:97
@ M_NONE
Definition: 8051_ops.h:94
op8051
Definition: 8051_ops.h:40
@ OP_RR
Definition: 8051_ops.h:71
@ OP_CALL
Definition: 8051_ops.h:45
@ OP_JZ
Definition: 8051_ops.h:61
@ OP_SWAP
Definition: 8051_ops.h:75
@ OP_MOV
Definition: 8051_ops.h:62
@ OP_INVALID
Definition: 8051_ops.h:41
@ OP_JNC
Definition: 8051_ops.h:59
@ OP_RRC
Definition: 8051_ops.h:72
@ OP_DA
Definition: 8051_ops.h:49
@ OP_ORL
Definition: 8051_ops.h:65
@ OP_CJNE
Definition: 8051_ops.h:46
@ OP_NOP
Definition: 8051_ops.h:64
@ OP_CLR
Definition: 8051_ops.h:47
@ OP_ANL
Definition: 8051_ops.h:44
@ OP_DIV
Definition: 8051_ops.h:51
@ OP_SETB
Definition: 8051_ops.h:73
@ OP_RL
Definition: 8051_ops.h:69
@ OP_RLC
Definition: 8051_ops.h:70
@ OP_INC
Definition: 8051_ops.h:53
@ OP_JBC
Definition: 8051_ops.h:55
@ OP_JC
Definition: 8051_ops.h:56
@ OP_RET
Definition: 8051_ops.h:68
@ OP_PUSH
Definition: 8051_ops.h:67
@ OP_ADD
Definition: 8051_ops.h:42
@ OP_MUL
Definition: 8051_ops.h:63
@ OP_SUBB
Definition: 8051_ops.h:74
@ OP_JB
Definition: 8051_ops.h:54
@ OP_ADDC
Definition: 8051_ops.h:43
@ OP_JNZ
Definition: 8051_ops.h:60
@ OP_DEC
Definition: 8051_ops.h:50
@ OP_XRL
Definition: 8051_ops.h:77
@ OP_CPL
Definition: 8051_ops.h:48
@ OP_XCH
Definition: 8051_ops.h:76
@ OP_JNB
Definition: 8051_ops.h:58
@ OP_POP
Definition: 8051_ops.h:66
@ OP_JMP
Definition: 8051_ops.h:57
@ OP_DJNZ
Definition: 8051_ops.h:52
static _8051_op_t _8051_ops[]
Definition: 8051_ops.h:113
static ut8 arg_bit(ut8 bit_addr)
Definition: 8051_ops.h:31
#define RET
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
@ MEM
Definition: inflate.h:51
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
#define AND
Definition: ansidecl.h:254
#define OR
Definition: rsp_idec.c:210
#define XOR
Definition: rsp_idec.c:212
#define NOP
Definition: rsp_idec.c:182
#define ADD
Definition: rsp_idec.c:200
_RzAnalysisOpType
Definition: rz_analysis.h:360
#define MUL(x, y)
#define DIV(x, y)
#define JMP(tgt)
#define SUB(ns, call)
#define CAST
Definition: str.c:3075
argtype8051 arg2
Definition: 8051_ops.h:109
argtype8051 arg1
Definition: 8051_ops.h:108
_RzAnalysisOpType type
Definition: 8051_ops.h:104
argtype8051 arg3
Definition: 8051_ops.h:110
op8051 instr
Definition: 8051_ops.h:103
size_t len
Definition: 8051_ops.h:106
int cycles
Definition: 8051_ops.h:102
argmask8051 mask
Definition: 8051_ops.h:107
char * string
Definition: 8051_ops.h:105
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58