├── README.md └── big_script_tool.py /README.md: -------------------------------------------------------------------------------- 1 | # BIOS Guard Script tool 2 | 3 | The tool allows you to assemble and disassemble BIOS Guard script. 4 | 5 | ## Assembly 6 | 7 | To assemble a script, you need to use `big-script-tool.py -a `. 8 | Assembled script will be saved to file `_assembled.bin`. 9 | 10 | Also you can use class `BigScript` directly: 11 | ``` 12 | script = BigScript(code_string=src) 13 | script.to_bytes() 14 | ``` 15 | or 16 | ``` 17 | script = BigScript() 18 | script.assemble(src) 19 | script.to_bytes() 20 | ``` 21 | 22 | ### Operands 23 | 24 | The operands are: 25 | * buffers 26 | * flash pointers 27 | * registers 28 | * immediate values 29 | * labels 30 | 31 | **Buffers**: `buffer` (or `b`). Storages of the data. 32 | `buffer0` points to the actual BGUP. Other buffers are temporal. 33 | ``` 34 | set b0 0xAA00 35 | add b0 0x1 36 | ``` 37 | 38 | **Flash pointers**: `flash` (or `f`). Stores some linear address of the flash. 39 | ``` 40 | set f0 0xA00000 41 | sub f0 0x10 42 | ``` 43 | **Registers**: `r` - a little storage of the temporal data. 44 | ``` 45 | set r1 0x10 46 | set r2 0x20 47 | add r1 r2 48 | and r1 0x30 49 | ``` 50 | **Imm values**: `` or `0x` if you prefer to use hex. ***Please note***, that hex numbers are start only with `0x` prefix. If you write something like `10000h` it will be interpreted as a decimal number. 51 | 52 | **Labels**: `_` - an arbitrary script line name. Can be used only in control flow instructions. 53 | ***Please note***, that labels start with `_` and must not end with symbols like `:`. If you use that symbol, you will need to refer to the label like `jmp _label:`. 54 | ``` 55 | _loop 56 | sub r1 r2 57 | cmp r1 0x0 58 | jne _loop 59 | ``` 60 | 61 | ### Opcodes 62 | 63 | | Opcode name | Operands | Info | 64 | |-|-|-| 65 | | start | - | marks the start of the script | 66 | | store | `flash ptr, buffer, register` | write data from a buffer to the flash | 67 | | store | `flash ptr, buffer, immediate value` | write data from a buffer to the flash | 68 | | load | `buffer, flash ptr, register` | read data from the flash to the buffer | 69 | | load | `buffer, flash ptr, immediate value` | read data from the flash to the buffer | 70 | | eraseblk | `flash ptr` | Erase flash blk | 71 | | eraseblk64kb | `flash ptr` | Erase 64kb flash block | 72 | | add | `register, register` | | 73 | | add | `register, immediate value` | | 74 | | add | `buffer, register` | | 75 | | add | `buffer, immediate value` | | 76 | | add | `flash ptr, register` | | 77 | | add | `flash ptr, immediate value` | | 78 | | sub | `register, register` | | 79 | | sub | `register, immediate value` | | 80 | | sub | `buffer, register` | | 81 | | sub | `buffer, immediate value` | | 82 | | sub | `flash ptr, register` | | 83 | | sub | `flash ptr, immediate value` | | 84 | | and | `register, register` | | 85 | | and | `register, immediate value` | | 86 | | or | `register, register` | | 87 | | or | `register, immediate value` | | 88 | | shr | `register, immediate value` | | 89 | | shl | `register, immediate value` | | 90 | | ror | `register, immediate value` | | 91 | | rol | `register, immediate value` | | 92 | | set | `register, register` | | 93 | | set | `register, immediate value` | | 94 | | set | `buffer, register` | Set an offset from the beggining of the buffer | 95 | | set | `buffer, immediate value` | Set an offset from the beggining of the buffer | 96 | | set | `flash ptr, register` | Set a linear address of the flash | 97 | | set | `flash ptr, immediate value` | Set a linear address of the flash | 98 | | loadbyte | `register, buffer` | | 99 | | loadword | `register, buffer` | | 100 | | loaddword | `register, buffer` | | 101 | | storebyte | `buffer, register` | | 102 | | storeword | `buffer, register` | | 103 | | storedword | `buffer, register` | | 104 | | cmp | `register, register` | | 105 | | cmp | `register, immediate value` | | 106 | | cmp | `buffer, register` | | 107 | | cmp | `buffer, immediate value` | | 108 | | cmp | `flash ptr, register` | | 109 | | cmp | `flash ptr, immediate value` | | 110 | | cmp | `buffer, buffer, register` | Compare buffers with specified length | 111 | | cmp | `buffer, buffer, immediate value` | Compare buffers with specified length | 112 | | copy | `buffer, buffer, register` | Copy data with the specified length | 113 | | copy | `buffer, buffer, immediate value` | Copy data with the specified length | 114 | | jmp | `label` (or `imm`) | Uncoditional jump to the label. Also you can use a line number directly. | 115 | | je | `label` (or `imm`) | Coditional jump to the label. Also you can use a line number directly.| 116 | | jne | `label`(or `imm`) | Coditional jump to the label. Also you can use a line number directly. | 117 | | jg | `label` (or `imm`) | Coditional jump to the label. Also you can use a line number directly. | 118 | | jge | `label` (or `imm`) | Coditional jump to the label. Also you can use a line number directly. | 119 | | jl | `label` (or `imm`) | Coditional jump to the label. Also you can use a line number directly. | 120 | | jle | `label` (or `imm`) | Coditional jump to the label. Also you can use a line number directly. | 121 | | jmp | `register` | Uncoditional jump to the line number stored in register. | 122 | | log | `immediate value, register` | Write data from second operand to the BiG Log. The BiG log needs to be setup properly. | 123 | | log | `immediate value, immediate value` | Write data from second operand to the BiG Log. The BiG log needs to be setup properly. | 124 | | rdsts | `register` | Read status of previous operation into register. | 125 | | rand | `register` | | 126 | | sleep | `immediate value` | | 127 | | end | - | | 128 | 129 | 130 | ## Disassembly 131 | 132 | To disassemble a script, you need to use `big-script-tool.py -d `. 133 | Disassembled script will be saved to file `_disassembled.txt`. 134 | 135 | Also you can use class ` 136 | BigScript` directly: 137 | ``` 138 | script = BigScript(code_bytes=bin_script) 139 | script.to_string() 140 | ``` 141 | or 142 | ``` 143 | script = BigScript() 144 | script.disassemble(bin_script) 145 | script.to_string() 146 | ``` 147 | -------------------------------------------------------------------------------- /big_script_tool.py: -------------------------------------------------------------------------------- 1 | from optparse import OptionParser, make_option 2 | 3 | import re 4 | import struct 5 | 6 | INSTR_LEN = 8 7 | MAX_OPERANDS = 3 8 | OPCODE_LEN = 2 9 | 10 | OP1_NUM = 0 11 | OP2_NUM = 1 12 | OP3_NUM = 2 13 | 14 | # 15 | # @TODO: take it out of here (json probably) 16 | # 17 | opcodes = { 18 | 0x00: { 'name': 'nop', 19 | 'operands': ['unused', 'unused', 'unused'] }, 20 | 0x01: { 'name': 'begin', 21 | 'operands': ['unused', 'unused', 'unused'] }, 22 | 0x10: { 'name': 'write', 23 | 'operands': ['flash', 'buff', 'reg'] }, 24 | 0x11: { 'name': 'write', 25 | 'operands': ['flash', 'buff', 'imm'] }, 26 | 0x12: { 'name': 'read', 27 | 'operands': ['buff', 'flash', 'reg'] }, 28 | 0x13: { 'name': 'read', 29 | 'operands': ['buff', 'flash', 'imm'] }, 30 | 0x14: { 'name': 'eraseblk', 31 | 'operands': ['flash', 'unused', 'unused'] }, 32 | 0x15: { 'name': 'erase64kblk', 33 | 'operands': ['flash', 'unused', 'unused'] }, 34 | 0x20: { 'name': 'eccmdwr', 35 | 'operands': ['reg', 'unused', 'unused'] }, 36 | 0x21: { 'name': 'eccmdwr', 37 | 'operands': ['unused', 'unused', 'imm'] }, 38 | 0x22: { 'name': 'ecstsrd', 39 | 'operands': ['reg', 'unused', 'unused'] }, 40 | 0x23: { 'name': 'ecdatawr', 41 | 'operands': ['reg', 'unused', 'unused'] }, 42 | 0x24: { 'name': 'ecdatawr', 43 | 'operands': ['unused', 'unused', 'imm'] }, 44 | 0x25: { 'name': 'ecdatard', 45 | 'operands': ['reg', 'unused', 'unused'] }, 46 | 0x30: { 'name': 'add', 47 | 'operands': ['reg', 'reg', 'unused'] }, 48 | 0x31: { 'name': 'add', 49 | 'operands': ['reg', 'unused', 'imm'] }, 50 | 0x32: { 'name': 'add', 51 | 'operands': ['buff', 'reg', 'unused'] }, 52 | 0x33: { 'name': 'add', 53 | 'operands': ['buff', 'unused', 'imm'] }, 54 | 0x34: { 'name': 'add', 55 | 'operands': ['flash', 'reg', 'unused'] }, 56 | 0x35: { 'name': 'add', 57 | 'operands': ['flash', 'unused', 'imm'] }, 58 | 0x36: { 'name': 'sub', 59 | 'operands': ['reg', 'reg', 'unused'] }, 60 | 0x37: { 'name': 'sub', 61 | 'operands': ['reg', 'unused', 'imm'] }, 62 | 0x38: { 'name': 'sub', 63 | 'operands': ['buff', 'reg', 'unused'] }, 64 | 0x39: { 'name': 'sub', 65 | 'operands': ['buff', 'unused', 'imm'] }, 66 | 0x3a: { 'name': 'sub', 67 | 'operands': ['flash', 'reg', 'unused'] }, 68 | 0x3b: { 'name': 'sub', 69 | 'operands': ['flash', 'unused', 'imm'] }, 70 | 0x40: { 'name': 'and', 71 | 'operands': ['reg', 'reg', 'unused'] }, 72 | 0x41: { 'name': 'and', 73 | 'operands': ['reg', 'unused', 'imm'] }, 74 | 0x42: { 'name': 'or', 75 | 'operands': ['reg', 'reg', 'unused'] }, 76 | 0x43: { 'name': 'or', 77 | 'operands': ['reg', 'unused', 'imm'] }, 78 | 0x44: { 'name': 'shiftr', 79 | 'operands': ['reg', 'unused', 'imm'] }, 80 | 0x45: { 'name': 'shiftl', 81 | 'operands': ['reg', 'unused', 'imm'] }, 82 | 0x46: { 'name': 'rotater', 83 | 'operands': ['reg', 'unused', 'imm'] }, 84 | 0x47: { 'name': 'rotatel', 85 | 'operands': ['reg', 'unused', 'imm'] }, 86 | 0x50: { 'name': 'set', 87 | 'operands': ['reg', 'reg', 'unused'] }, 88 | 0x51: { 'name': 'set', 89 | 'operands': ['reg', 'unused', 'imm'] }, 90 | 0x52: { 'name': 'set', 91 | 'operands': ['buff', 'reg', 'unused'] }, 92 | 0x53: { 'name': 'set', 93 | 'operands': ['buff', 'unused', 'imm'] }, 94 | 0x54: { 'name': 'set', 95 | 'operands': ['flash', 'reg', 'unused'] }, 96 | 0x55: { 'name': 'set', 97 | 'operands': ['flash', 'unused', 'imm'] }, 98 | 0x60: { 'name': 'loadbyte', 99 | 'operands': ['reg', 'buff', 'unused'] }, 100 | 0x61: { 'name': 'loadword', 101 | 'operands': ['reg', 'buff', 'unused'] }, 102 | 0x62: { 'name': 'loaddword', 103 | 'operands': ['reg', 'buff', 'unused'] }, 104 | 0x63: { 'name': 'storebyte', 105 | 'operands': ['buff', 'reg', 'unused'] }, 106 | 0x64: { 'name': 'storeword', 107 | 'operands': ['buff', 'reg', 'unused'] }, 108 | 0x65: { 'name': 'storedword', 109 | 'operands': ['buff', 'reg', 'unused'] }, 110 | 0x70: { 'name': 'compare', 111 | 'operands': ['reg', 'reg', 'unused'] }, 112 | 0x71: { 'name': 'compare', 113 | 'operands': ['reg', 'unused', 'imm'] }, 114 | 0x72: { 'name': 'compare', 115 | 'operands': ['buff', 'reg', 'unused'] }, 116 | 0x73: { 'name': 'compare', 117 | 'operands': ['buff', 'unused', 'imm'] }, 118 | 0x74: { 'name': 'compare', 119 | 'operands': ['flash', 'reg', 'unused'] }, 120 | 0x75: { 'name': 'compare', 121 | 'operands': ['flash', 'unused', 'imm'] }, 122 | 0x76: { 'name': 'compare', 123 | 'operands': ['buff', 'buff', 'reg'] }, 124 | 0x77: { 'name': 'compare', 125 | 'operands': ['buff', 'buff', 'imm'] }, 126 | 0x80: { 'name': 'copy', 127 | 'operands': ['buff', 'buff', 'reg'] }, 128 | 0x81: { 'name': 'copy', 129 | 'operands': ['buff', 'buff', 'imm'] }, 130 | 0x90: { 'name': 'jmp', 131 | 'operands': ['unused', 'unused', 'imm'] }, 132 | 0x91: { 'name': 'je', 133 | 'operands': ['unused', 'unused', 'imm'] }, 134 | 0x92: { 'name': 'jne', 135 | 'operands': ['unused', 'unused', 'imm'] }, 136 | 0x93: { 'name': 'jg', 137 | 'operands': ['unused', 'unused', 'imm'] }, 138 | 0x94: { 'name': 'jge', 139 | 'operands': ['unused', 'unused', 'imm'] }, 140 | 0x95: { 'name': 'jl', 141 | 'operands': ['unused', 'unused', 'imm'] }, 142 | 0x96: { 'name': 'jle', 143 | 'operands': ['unused', 'unused', 'imm'] }, 144 | 0x97: { 'name': 'jmp', 145 | 'operands': ['reg', 'unused', 'unused'] }, 146 | 0xa0: { 'name': 'log', 147 | 'operands': ['imm', 'reg', 'unused'] }, 148 | 0xa1: { 'name': 'log', 149 | 'operands': ['imm', 'unused', 'imm'] }, 150 | 0xb0: { 'name': 'rdsts', 151 | 'operands': ['reg', 'unused', 'unused'] }, 152 | 0xb1: { 'name': 'rdkeyslot', 153 | 'operands': ['reg', 'unused', 'unused'] }, 154 | 0xb2: { 'name': 'rdrand', 155 | 'operands': ['reg', 'unused', 'unused'] }, 156 | 0xc0: { 'name': 'stall', 157 | 'operands': ['unused', 'unused', 'imm'] }, 158 | 0xc1: { 'name': 'rdts', 159 | 'operands': ['reg', 'unused', 'unused'] }, 160 | 0xc2: { 'name': 'setts', 161 | 'operands': ['unused', 'unused', 'unused'] }, 162 | 0xc3: { 'name': 'clearts', 163 | 'operands': ['unused', 'unused', 'unused'] }, 164 | 0xff: { 'name': 'end', 165 | 'operands': ['unused', 'unused', 'unused'] } 166 | } 167 | 168 | class BigScript: 169 | def __init__(self, code_string = None, code_bytes = None): 170 | global opcodes 171 | 172 | self.instructions = [] 173 | self.op_dict = opcodes 174 | 175 | if not code_string is None: 176 | self.assemble(code_string) 177 | self.code_string = code_string 178 | elif not code_bytes is None: 179 | self.disassemble(code_bytes) 180 | self.code_bytes = code_bytes 181 | 182 | def assemble(self, code_string): 183 | all_lines = [line.strip() for line in code_string.splitlines()] 184 | labels = {} 185 | 186 | # remove labels from code listing and replace it with actual line numbers 187 | offset = 0 188 | for i in range(0, len(all_lines)): 189 | if all_lines[i][0] == '_': 190 | labels[all_lines[i]] = i-offset 191 | offset+=1 192 | 193 | code_lines = [line for line in all_lines if not line[0] == '_'] 194 | code_lines_count = len(code_lines) 195 | for i in range(0, code_lines_count): 196 | line = code_lines[i] 197 | for label in labels: 198 | if label in line: 199 | code_lines[i] = line.replace(label, str(labels[label])) 200 | 201 | 202 | self.instructions = [Instruction(self.op_dict, i*INSTR_LEN, instr_string=code_lines[i]) for i in range(0, code_lines_count)] 203 | 204 | if not self.instructions[0].is_start(): 205 | print('WARNING: the input script doesn\'t start with `begin` opcode. ACM will reject this script.') 206 | if not self.instructions[-1].is_end(): 207 | print('WARNING: the input script doesn\'t end with `end` opcode. ACM will reject this script.') 208 | 209 | self.code_bytes = b'' 210 | for instr in self.instructions: 211 | self.code_bytes += instr.to_bytes() 212 | 213 | def disassemble(self, code_bytes): 214 | code_len = len(code_bytes) 215 | if not code_len % INSTR_LEN == 0: 216 | raise Exception('ERROR: code size need to be aligned to 8. The input script is corrupted.') 217 | 218 | code_lines_count = code_len // INSTR_LEN 219 | code_lines = [code_bytes[i:i + INSTR_LEN] for i in range(0, code_len, INSTR_LEN)] 220 | self.instructions = [Instruction(self.op_dict, i*INSTR_LEN, instr_bytes=code_lines[i]) for i in range(0, code_lines_count)] 221 | 222 | if not self.instructions[0].is_start(): 223 | print('WARNING: the input script doesn\'t start with `begin` opcode. It may be corrupted.') 224 | if not self.instructions[-1].is_end(): 225 | print('WARNING: the input script doesn\'t end with `end` opcode. It may be corrupted.') 226 | 227 | labels = [] 228 | for instr in [instr for instr in self.instructions if instr.is_jump()]: 229 | label_addr = instr.get_jump_line() 230 | if not label_addr in labels: 231 | labels.append(label_addr) 232 | 233 | code_str_lines = [] 234 | for instr in self.instructions: 235 | if instr.is_jump(): 236 | code_str_lines.append('\t' + instr.get_opcode_name() + ' ' + '_lb' + str(instr.get_jump_line())) 237 | else: 238 | code_str_lines.append('\t' + instr.to_string()) 239 | 240 | labels.sort() 241 | offset = 0 242 | for label in labels: 243 | code_str_lines.insert(label+offset, '_lb'+str(label)+':') 244 | offset+=1 245 | 246 | self.code_str = '\n'.join(code_str_lines) 247 | 248 | def to_string(self): 249 | return self.code_str 250 | 251 | def to_bytes(self): 252 | return self.code_bytes 253 | 254 | 255 | class Instruction: 256 | def __init__(self, opcodes_dict, instr_addr, instr_string = None, instr_bytes = None): 257 | self.op_dict = opcodes_dict 258 | self.addr = instr_addr 259 | self.opcode_name = "" 260 | self.opcode_num = None 261 | self.operands = [None, None, None] 262 | 263 | if not instr_string is None: 264 | self.assemble(instr_string) 265 | self.instr_str = instr_string 266 | elif not instr_bytes is None: 267 | self.disassemble(instr_bytes) 268 | self.instr_bytes = instr_bytes 269 | 270 | def assemble(self, instr_string): 271 | instr_str_splt = [part.strip() for part in instr_string.split()] 272 | self.opcode_name = instr_str_splt[0] 273 | 274 | operands_str = instr_str_splt[1:] 275 | operands_count = len(operands_str) 276 | used_operands_mask = [] 277 | for i in range(0, operands_count): 278 | op = Operand(self.addr, operands_str[i]) 279 | used_operands_mask.append(op.get_type()) 280 | self.operands[i] = op 281 | 282 | # proccessing the case of various opcodes with same names 283 | for current_op_num in self.op_dict: 284 | opcode = self.op_dict[current_op_num] 285 | if opcode['name'] == self.opcode_name: 286 | used_ops = [op for op in opcode['operands'] if not op == 'unused'] 287 | if used_ops == used_operands_mask: 288 | true_operands_mask = opcode['operands'] 289 | self.opcode_num = current_op_num 290 | 291 | if self.opcode_num is None: 292 | raise Exception('ERROR: unknown opcode ' + self.opcode_name + ' with operands ' + str(used_operands_mask) + ' at ' + '0x%X' % self.addr + '') 293 | 294 | # fix operands numbers 295 | for i in range(0, operands_count): 296 | operand = self.operands[i] 297 | 298 | if operand.get_type() == true_operands_mask[i]: 299 | continue 300 | 301 | for j in range(i, MAX_OPERANDS): 302 | if true_operands_mask[j] == operand.get_type(): 303 | operand.set_num(j) 304 | tmp = self.operands[j] 305 | self.operands[j] = operand 306 | self.operands[i] = tmp 307 | 308 | for i in range(0, MAX_OPERANDS): 309 | if self.operands[i] is None: 310 | self.operands[i] = Operand(self.addr, op_num=i) 311 | self.operands[i].set_type('unused') 312 | self.operands[i].set_value(0) 313 | 314 | self.instr_bytes = struct.pack('HBBI', self.opcode_num, self.operands[0].get_value(), self.operands[1].get_value(), self.operands[2].get_value()) 315 | 316 | def disassemble(self, instr_bytes): 317 | self.opcode_num, op1, op2, op3 = struct.unpack('HBBI', instr_bytes) 318 | 319 | if not self.opcode_num in self.op_dict: 320 | raise Exception('ERROR: unknown opcode ' + '0x%X' % self.opcode_num + ' at ' + '0x%X' % self.addr + '') 321 | 322 | instr_dict = self.op_dict[self.opcode_num] 323 | self.operands[OP1_NUM] = Operand(self.addr, op_value=op1, op_num=OP1_NUM, root_instr_dict=instr_dict) 324 | self.operands[OP2_NUM] = Operand(self.addr, op_value=op2, op_num=OP2_NUM, root_instr_dict=instr_dict) 325 | self.operands[OP3_NUM] = Operand(self.addr, op_value=op3, op_num=OP3_NUM, root_instr_dict=instr_dict) 326 | self.opcode_name = self.op_dict[self.opcode_num]['name'] 327 | 328 | self.instr_str = self.opcode_name 329 | for op in self.operands: 330 | if not op.is_unused(): 331 | self.instr_str += ' ' + op.to_string() 332 | 333 | 334 | def to_bytes(self): 335 | return self.instr_bytes 336 | 337 | def to_string(self): 338 | return self.instr_str 339 | 340 | def is_start(self): 341 | # @TODO: make it not that ugly 342 | return self.opcode_num == 0x1 343 | 344 | def is_end(self): 345 | # @TODO: make it not that ugly 346 | return self.opcode_num == 0xff 347 | 348 | def is_jump(self): 349 | # @TODO: make it not that ugly 350 | return self.opcode_name[0] == 'j' 351 | 352 | def get_operand(self, num): 353 | return self.operands[num] 354 | 355 | def get_opcode_name(self): 356 | return self.opcode_name 357 | 358 | def get_jump_line(self): 359 | if self.is_jump(): 360 | return self.get_operand(OP3_NUM).get_value() 361 | 362 | class Operand: 363 | def __init__(self, root_instr_addr, op_string = None, op_value = None, op_num = None, root_instr_dict = None): 364 | self.instr_dict = root_instr_dict 365 | self.instr_addr = root_instr_addr 366 | self.op_type = None 367 | self.op_str = None 368 | self.op_value = op_value 369 | self.op_num = op_num 370 | 371 | if not op_string is None: 372 | self.assemble(op_string) 373 | self.op_str = op_string 374 | elif not op_value is None: 375 | self.disassemble(op_value) 376 | self.op_value = op_value 377 | 378 | def assemble(self, op_string): 379 | first_chr = op_string[0] 380 | if first_chr == 'f': 381 | self.op_type = 'flash' 382 | elif first_chr == 'b': 383 | self.op_type = 'buff' 384 | elif first_chr == 'r': 385 | self.op_type = 'reg' 386 | elif first_chr.isdigit(): 387 | self.op_type = 'imm' 388 | else: 389 | raise Exception('ERROR: unknown type of operand ' + op_string + ' at addr ' + '0x%X' % self.instr_addr) 390 | 391 | self.op_value = 0 392 | possible_values = re.findall('0[xX][0-9a-fA-F]+|\\d+', op_string) 393 | for value_str in possible_values: 394 | value_base = 10 + int('0x' in value_str) * 6 395 | value = int(value_str, value_base) 396 | if not value == 0: 397 | self.op_value = value 398 | break 399 | 400 | def disassemble(self, op_value): 401 | if self.instr_dict is None: 402 | raise Exception('ERROR: instruction dict need to be passed for operands dissasembly (addr ' + '0x%X' % self.instr_addr + ')') 403 | if self.op_value is None: 404 | raise Exception('ERROR: operand value need to be passed for operands dissasembly (addr ' + '0x%X' % self.instr_addr + ')') 405 | 406 | operands_mask = self.instr_dict['operands'] 407 | self.op_type = operands_mask[self.op_num] 408 | if self.op_type == 'flash': 409 | self.op_str = 'F%X' % self.op_value 410 | elif self.op_type == 'buff': 411 | self.op_str = 'B%X' % self.op_value 412 | elif self.op_type == 'reg': 413 | self.op_str = 'I%X' % self.op_value 414 | elif self.op_type == 'imm': 415 | self.op_str = '0x%X' % self.op_value 416 | 417 | def get_type(self): 418 | return self.op_type 419 | 420 | def get_num(self): 421 | return self.op_num 422 | 423 | def get_value(self): 424 | return self.op_value 425 | 426 | def set_num(self, num): 427 | self.op_num = num 428 | 429 | def set_type(self, optype): 430 | self.op_type = optype 431 | 432 | def set_value(self, value): 433 | self.op_value = value 434 | 435 | def to_string(self): 436 | return self.op_str 437 | 438 | def to_bytes(self): 439 | if self.op_num == OP3_NUM: 440 | return struct.pack('