Rizin
unix-like reverse engineering framework and cli tools
asm_x86_nz.c File Reference
#include <rz_flag.h>
#include <rz_core.h>
#include <rz_asm.h>
#include <rz_lib.h>
#include <rz_types.h>
#include <stdio.h>
#include <string.h>

Go to the source code of this file.

Classes

struct  operand_t
 
struct  Opcode_t
 
struct  lookup_t
 

Macros

#define ENCODING_SHIFT   0
 
#define OPTYPE_SHIFT   6
 
#define REGMASK_SHIFT   16
 
#define OPSIZE_SHIFT   24
 
#define OT_REGMEM   (1 << (ENCODING_SHIFT + 0))
 
#define OT_SPECIAL   (1 << (ENCODING_SHIFT + 1))
 
#define OT_IMMEDIATE   (1 << (ENCODING_SHIFT + 2))
 
#define OT_JMPADDRESS   (1 << (ENCODING_SHIFT + 3))
 
#define OT_REGALL   (0xff << REGMASK_SHIFT)
 
#define OT_MEMORY   (1 << (OPTYPE_SHIFT + 0))
 
#define OT_CONSTANT   (1 << (OPTYPE_SHIFT + 1))
 
#define OT_GPREG   ((1 << (OPTYPE_SHIFT + 2)) | OT_REGALL)
 
#define OT_SEGMENTREG   ((1 << (OPTYPE_SHIFT + 3)) | OT_REGALL)
 
#define OT_FPUREG   ((1 << (OPTYPE_SHIFT + 4)) | OT_REGALL)
 
#define OT_MMXREG   ((1 << (OPTYPE_SHIFT + 5)) | OT_REGALL)
 
#define OT_XMMREG   ((1 << (OPTYPE_SHIFT + 6)) | OT_REGALL)
 
#define OT_CONTROLREG   ((1 << (OPTYPE_SHIFT + 7)) | OT_REGALL)
 
#define OT_DEBUGREG   ((1 << (OPTYPE_SHIFT + 8)) | OT_REGALL)
 
#define OT_SREG   ((1 << (OPTYPE_SHIFT + 9)) | OT_REGALL)
 
#define OT_REGTYPE   ((OT_GPREG | OT_SEGMENTREG | OT_FPUREG | OT_MMXREG | OT_XMMREG | OT_CONTROLREG | OT_DEBUGREG) & ~OT_REGALL)
 
#define OT_REG(num)   ((1 << (REGMASK_SHIFT + (num))) | OT_REGTYPE)
 
#define OT_UNKNOWN   (0 << OPSIZE_SHIFT)
 
#define OT_BYTE   (1 << OPSIZE_SHIFT)
 
#define OT_WORD   (2 << OPSIZE_SHIFT)
 
#define OT_DWORD   (4 << OPSIZE_SHIFT)
 
#define OT_QWORD   (8 << OPSIZE_SHIFT)
 
#define OT_OWORD   (16 << OPSIZE_SHIFT)
 
#define OT_TBYTE   (32 << OPSIZE_SHIFT)
 
#define ALL_SIZE   (OT_BYTE | OT_WORD | OT_DWORD | OT_QWORD | OT_OWORD)
 
#define OT_FPUSIZE   (OT_DWORD | OT_QWORD | OT_TBYTE)
 
#define OT_XMMSIZE   (OT_DWORD | OT_QWORD | OT_OWORD)
 
#define OT_REGMEMOP(type)   (OT_##type##REG | OT_MEMORY | OT_REGMEM)
 
#define OT_REGONLYOP(type)   (OT_##type##REG | OT_REGMEM)
 
#define OT_MEMONLYOP   (OT_MEMORY | OT_REGMEM)
 
#define OT_MEMIMMOP   (OT_MEMORY | OT_IMMEDIATE)
 
#define OT_REGSPECOP(type)   (OT_##type##REG | OT_SPECIAL)
 
#define OT_IMMOP   (OT_CONSTANT | OT_IMMEDIATE)
 
#define OT_MEMADDROP   (OT_MEMORY | OT_IMMEDIATE)
 
#define SPECIAL_SPEC   0x00010000
 
#define SPECIAL_MASK   0x00000007
 
#define MAX_OPERANDS   3
 
#define MAX_REPOP_LENGTH   20
 
#define is_valid_registers(op)
 

Typedefs

typedef enum tokentype_t x86newTokenType
 
typedef enum register_t Register
 
typedef struct operand_t Operand
 
typedef struct Opcode_t Opcode
 
typedef struct lookup_t LookupTable
 

Enumerations

enum  tokentype_t { TT_EOF , TT_WORD , TT_NUMBER , TT_SPECIAL }
 
enum  register_t {
  X86R_UNDEFINED = -1 , X86R_EAX = 0 , X86R_ECX , X86R_EDX ,
  X86R_EBX , X86R_ESP , X86R_EBP , X86R_ESI ,
  X86R_EDI , X86R_EIP , X86R_AX = 0 , X86R_CX ,
  X86R_DX , X86R_BX , X86R_SP , X86R_BP ,
  X86R_SI , X86R_DI , X86R_AL = 0 , X86R_CL ,
  X86R_DL , X86R_BL , X86R_AH , X86R_CH ,
  X86R_DH , X86R_BH , X86R_RAX = 0 , X86R_RCX ,
  X86R_RDX , X86R_RBX , X86R_RSP , X86R_RBP ,
  X86R_RSI , X86R_RDI , X86R_RIP , X86R_R8 = 0 ,
  X86R_R9 , X86R_R10 , X86R_R11 , X86R_R12 ,
  X86R_R13 , X86R_R14 , X86R_R15 , X86R_CS = 0 ,
  X86R_SS , X86R_DS , X86R_ES , X86R_FS ,
  X86R_GS , X86R_CR0 = 0 , X86R_CR1 , X86R_CR2 ,
  X86R_CR3 , X86R_CR4 , X86R_CR5 , X86R_CR6 ,
  X86R_CR7 , X86R_DR0 = 0 , X86R_DR1 , X86R_DR2 ,
  X86R_DR3 , X86R_DR4 , X86R_DR5 , X86R_DR6 ,
  X86R_DR7
}
 

Functions

static ut64 getnum (RzAsm *a, const char *s)
 
static bool is_debug_or_control (Operand op)
 
static ut8 getsib (const ut8 sib)
 
static int is_al_reg (const Operand *op)
 
static int oprep (RzAsm *a, ut8 *data, const Opcode *op)
 
static int process_16bit_group_1 (RzAsm *a, ut8 *data, const Opcode *op, int op1)
 
static int process_group_1 (RzAsm *a, ut8 *data, const Opcode *op)
 
static int process_group_2 (RzAsm *a, ut8 *data, const Opcode *op)
 
static int process_1byte_op (RzAsm *a, ut8 *data, const Opcode *op, int op1)
 
static int opadc (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opadd (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opand (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opcmp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opsub (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opor (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opxadd (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opxor (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opneg (RzAsm *a, ut8 *data, const Opcode *op)
 
static int endbr64 (RzAsm *a, ut8 *data, const Opcode *op)
 
static int endbr32 (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opnot (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opsbb (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opbs (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opbswap (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opcall (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opcmov (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opmovx (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opaam (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opdec (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opidiv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opdiv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opimul (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opin (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opclflush (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opinc (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opint (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opjc (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oplea (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oples (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opmov (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opmovabs (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opmul (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oppop (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oppush (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opout (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oploop (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opret (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opretf (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opstos (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opset (RzAsm *a, ut8 *data, const Opcode *op)
 
static int optest (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opxchg (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opcdqe (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfcmov (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opffree (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfrstor (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfxch (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfucom (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfucomp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfaddp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfiadd (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfadd (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opficom (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opficomp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfild (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfldcw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfldenv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfbld (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfbstp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfxrstor (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfxsave (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfist (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfistp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfisttp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfstenv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfnstenv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfdiv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfdivp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfidiv (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfdivr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfdivrp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfidivr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfmul (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfmulp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfimul (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfsub (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfsubp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfisub (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfsubr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfsubrp (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfisubr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfnstcw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfstcw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfnstsw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfstsw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfnsave (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opfsave (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oplldt (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oplmsw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oplgdt (RzAsm *a, ut8 *data, const Opcode *op)
 
static int oplidt (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opsgdt (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opstmxcsr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opstr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opsidt (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opsldt (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opsmsw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opverr (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opverw (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opvmclear (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opvmon (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opvmptrld (RzAsm *a, ut8 *data, const Opcode *op)
 
static int opvmptrst (RzAsm *a, ut8 *data, const Opcode *op)
 
static x86newTokenType getToken (const char *str, size_t *begin, size_t *end)
 
static bool is_xmm_register (const char *token)
 
static bool is_mm_register (const char *token)
 
static bool is_st_register (const char *token)
 
static Register parseReg (RzAsm *a, const char *str, size_t *pos, ut32 *type)
 
static void parse_segment_offset (RzAsm *a, const char *str, size_t *pos, Operand *op, int reg_index)
 
static int parseOperand (RzAsm *a, const char *str, Operand *op, bool isrepop)
 
static int parseOpcode (RzAsm *a, const char *op, Opcode *out)
 
static int assemble (RzAsm *a, RzAsmOp *ao, const char *str)
 

Variables

const ut8 SEG_REG_PREFIXES [] = { 0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65 }
 
LookupTable oplookup []
 
RzAsmPlugin rz_asm_plugin_x86_nz
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ ALL_SIZE

#define ALL_SIZE   (OT_BYTE | OT_WORD | OT_DWORD | OT_QWORD | OT_OWORD)

Definition at line 56 of file asm_x86_nz.c.

◆ ENCODING_SHIFT

#define ENCODING_SHIFT   0

Definition at line 16 of file asm_x86_nz.c.

◆ is_valid_registers

#define is_valid_registers (   op)
Value:
if (is_debug_or_control(op->operands[0]) || is_debug_or_control(op->operands[1])) \
return -1;
static bool is_debug_or_control(Operand op)
Definition: asm_x86_nz.c:198
Definition: dis.c:32

Definition at line 79 of file asm_x86_nz.c.

◆ MAX_OPERANDS

#define MAX_OPERANDS   3

Definition at line 76 of file asm_x86_nz.c.

◆ MAX_REPOP_LENGTH

#define MAX_REPOP_LENGTH   20

Definition at line 77 of file asm_x86_nz.c.

◆ OPSIZE_SHIFT

#define OPSIZE_SHIFT   24

Definition at line 19 of file asm_x86_nz.c.

◆ OPTYPE_SHIFT

#define OPTYPE_SHIFT   6

Definition at line 17 of file asm_x86_nz.c.

◆ OT_BYTE

#define OT_BYTE   (1 << OPSIZE_SHIFT)

Definition at line 49 of file asm_x86_nz.c.

◆ OT_CONSTANT

#define OT_CONSTANT   (1 << (OPTYPE_SHIFT + 1))

Definition at line 32 of file asm_x86_nz.c.

◆ OT_CONTROLREG

#define OT_CONTROLREG   ((1 << (OPTYPE_SHIFT + 7)) | OT_REGALL)

Definition at line 38 of file asm_x86_nz.c.

◆ OT_DEBUGREG

#define OT_DEBUGREG   ((1 << (OPTYPE_SHIFT + 8)) | OT_REGALL)

Definition at line 39 of file asm_x86_nz.c.

◆ OT_DWORD

#define OT_DWORD   (4 << OPSIZE_SHIFT)

Definition at line 51 of file asm_x86_nz.c.

◆ OT_FPUREG

#define OT_FPUREG   ((1 << (OPTYPE_SHIFT + 4)) | OT_REGALL)

Definition at line 35 of file asm_x86_nz.c.

◆ OT_FPUSIZE

#define OT_FPUSIZE   (OT_DWORD | OT_QWORD | OT_TBYTE)

Definition at line 60 of file asm_x86_nz.c.

◆ OT_GPREG

#define OT_GPREG   ((1 << (OPTYPE_SHIFT + 2)) | OT_REGALL)

Definition at line 33 of file asm_x86_nz.c.

◆ OT_IMMEDIATE

#define OT_IMMEDIATE   (1 << (ENCODING_SHIFT + 2))

Definition at line 24 of file asm_x86_nz.c.

◆ OT_IMMOP

#define OT_IMMOP   (OT_CONSTANT | OT_IMMEDIATE)

Definition at line 69 of file asm_x86_nz.c.

◆ OT_JMPADDRESS

#define OT_JMPADDRESS   (1 << (ENCODING_SHIFT + 3))

Definition at line 25 of file asm_x86_nz.c.

◆ OT_MEMADDROP

#define OT_MEMADDROP   (OT_MEMORY | OT_IMMEDIATE)

Definition at line 70 of file asm_x86_nz.c.

◆ OT_MEMIMMOP

#define OT_MEMIMMOP   (OT_MEMORY | OT_IMMEDIATE)

Definition at line 67 of file asm_x86_nz.c.

◆ OT_MEMONLYOP

#define OT_MEMONLYOP   (OT_MEMORY | OT_REGMEM)

Definition at line 66 of file asm_x86_nz.c.

◆ OT_MEMORY

#define OT_MEMORY   (1 << (OPTYPE_SHIFT + 0))

Definition at line 31 of file asm_x86_nz.c.

◆ OT_MMXREG

#define OT_MMXREG   ((1 << (OPTYPE_SHIFT + 5)) | OT_REGALL)

Definition at line 36 of file asm_x86_nz.c.

◆ OT_OWORD

#define OT_OWORD   (16 << OPSIZE_SHIFT)

Definition at line 53 of file asm_x86_nz.c.

◆ OT_QWORD

#define OT_QWORD   (8 << OPSIZE_SHIFT)

Definition at line 52 of file asm_x86_nz.c.

◆ OT_REG

#define OT_REG (   num)    ((1 << (REGMASK_SHIFT + (num))) | OT_REGTYPE)

Definition at line 46 of file asm_x86_nz.c.

◆ OT_REGALL

#define OT_REGALL   (0xff << REGMASK_SHIFT)

Definition at line 28 of file asm_x86_nz.c.

◆ OT_REGMEM

#define OT_REGMEM   (1 << (ENCODING_SHIFT + 0))

Definition at line 22 of file asm_x86_nz.c.

◆ OT_REGMEMOP

#define OT_REGMEMOP (   type)    (OT_##type##REG | OT_MEMORY | OT_REGMEM)

Definition at line 64 of file asm_x86_nz.c.

◆ OT_REGONLYOP

#define OT_REGONLYOP (   type)    (OT_##type##REG | OT_REGMEM)

Definition at line 65 of file asm_x86_nz.c.

◆ OT_REGSPECOP

#define OT_REGSPECOP (   type)    (OT_##type##REG | OT_SPECIAL)

Definition at line 68 of file asm_x86_nz.c.

◆ OT_REGTYPE

Definition at line 43 of file asm_x86_nz.c.

◆ OT_SEGMENTREG

#define OT_SEGMENTREG   ((1 << (OPTYPE_SHIFT + 3)) | OT_REGALL)

Definition at line 34 of file asm_x86_nz.c.

◆ OT_SPECIAL

#define OT_SPECIAL   (1 << (ENCODING_SHIFT + 1))

Definition at line 23 of file asm_x86_nz.c.

◆ OT_SREG

#define OT_SREG   ((1 << (OPTYPE_SHIFT + 9)) | OT_REGALL)

Definition at line 40 of file asm_x86_nz.c.

◆ OT_TBYTE

#define OT_TBYTE   (32 << OPSIZE_SHIFT)

Definition at line 54 of file asm_x86_nz.c.

◆ OT_UNKNOWN

#define OT_UNKNOWN   (0 << OPSIZE_SHIFT)

Definition at line 48 of file asm_x86_nz.c.

◆ OT_WORD

#define OT_WORD   (2 << OPSIZE_SHIFT)

Definition at line 50 of file asm_x86_nz.c.

◆ OT_XMMREG

#define OT_XMMREG   ((1 << (OPTYPE_SHIFT + 6)) | OT_REGALL)

Definition at line 37 of file asm_x86_nz.c.

◆ OT_XMMSIZE

#define OT_XMMSIZE   (OT_DWORD | OT_QWORD | OT_OWORD)

Definition at line 61 of file asm_x86_nz.c.

◆ REGMASK_SHIFT

#define REGMASK_SHIFT   16

Definition at line 18 of file asm_x86_nz.c.

◆ SPECIAL_MASK

#define SPECIAL_MASK   0x00000007

Definition at line 74 of file asm_x86_nz.c.

◆ SPECIAL_SPEC

#define SPECIAL_SPEC   0x00010000

Definition at line 73 of file asm_x86_nz.c.

Typedef Documentation

◆ LookupTable

typedef struct lookup_t LookupTable

◆ Opcode

typedef struct Opcode_t Opcode

◆ Operand

typedef struct operand_t Operand

◆ Register

typedef enum register_t Register

◆ x86newTokenType

Enumeration Type Documentation

◆ register_t

enum register_t
Enumerator
X86R_UNDEFINED 
X86R_EAX 
X86R_ECX 
X86R_EDX 
X86R_EBX 
X86R_ESP 
X86R_EBP 
X86R_ESI 
X86R_EDI 
X86R_EIP 
X86R_AX 
X86R_CX 
X86R_DX 
X86R_BX 
X86R_SP 
X86R_BP 
X86R_SI 
X86R_DI 
X86R_AL 
X86R_CL 
X86R_DL 
X86R_BL 
X86R_AH 
X86R_CH 
X86R_DH 
X86R_BH 
X86R_RAX 
X86R_RCX 
X86R_RDX 
X86R_RBX 
X86R_RSP 
X86R_RBP 
X86R_RSI 
X86R_RDI 
X86R_RIP 
X86R_R8 
X86R_R9 
X86R_R10 
X86R_R11 
X86R_R12 
X86R_R13 
X86R_R14 
X86R_R15 
X86R_CS 
X86R_SS 
X86R_DS 
X86R_ES 
X86R_FS 
X86R_GS 
X86R_CR0 
X86R_CR1 
X86R_CR2 
X86R_CR3 
X86R_CR4 
X86R_CR5 
X86R_CR6 
X86R_CR7 
X86R_DR0 
X86R_DR1 
X86R_DR2 
X86R_DR3 
X86R_DR4 
X86R_DR5 
X86R_DR6 
X86R_DR7 

Definition at line 92 of file asm_x86_nz.c.

92  {
93  X86R_UNDEFINED = -1,
94  X86R_EAX = 0,
95  X86R_ECX,
96  X86R_EDX,
97  X86R_EBX,
98  X86R_ESP,
99  X86R_EBP,
100  X86R_ESI,
101  X86R_EDI,
102  X86R_EIP,
103  X86R_AX = 0,
104  X86R_CX,
105  X86R_DX,
106  X86R_BX,
107  X86R_SP,
108  X86R_BP,
109  X86R_SI,
110  X86R_DI,
111  X86R_AL = 0,
112  X86R_CL,
113  X86R_DL,
114  X86R_BL,
115  X86R_AH,
116  X86R_CH,
117  X86R_DH,
118  X86R_BH,
119  X86R_RAX = 0,
120  X86R_RCX,
121  X86R_RDX,
122  X86R_RBX,
123  X86R_RSP,
124  X86R_RBP,
125  X86R_RSI,
126  X86R_RDI,
127  X86R_RIP,
128  X86R_R8 = 0,
129  X86R_R9,
130  X86R_R10,
131  X86R_R11,
132  X86R_R12,
133  X86R_R13,
134  X86R_R14,
135  X86R_R15,
136  X86R_CS = 0,
137  X86R_SS,
138  X86R_DS,
139  X86R_ES,
140  X86R_FS,
141  X86R_GS, // Is this the right order?
142  X86R_CR0 = 0,
143  X86R_CR1,
144  X86R_CR2,
145  X86R_CR3,
146  X86R_CR4,
147  X86R_CR5,
148  X86R_CR6,
149  X86R_CR7,
150  X86R_DR0 = 0,
151  X86R_DR1,
152  X86R_DR2,
153  X86R_DR3,
154  X86R_DR4,
155  X86R_DR5,
156  X86R_DR6,
157  X86R_DR7
158 } Register;
@ X86R_R15
Definition: asm_x86_nz.c:135
@ X86R_BH
Definition: asm_x86_nz.c:118
@ X86R_R11
Definition: asm_x86_nz.c:131
@ X86R_RSI
Definition: asm_x86_nz.c:125
@ X86R_EDI
Definition: asm_x86_nz.c:101
@ X86R_R13
Definition: asm_x86_nz.c:133
@ X86R_CR7
Definition: asm_x86_nz.c:149
@ X86R_DH
Definition: asm_x86_nz.c:117
@ X86R_EIP
Definition: asm_x86_nz.c:102
@ X86R_ESI
Definition: asm_x86_nz.c:100
@ X86R_DR6
Definition: asm_x86_nz.c:156
@ X86R_CR3
Definition: asm_x86_nz.c:145
@ X86R_RSP
Definition: asm_x86_nz.c:123
@ X86R_FS
Definition: asm_x86_nz.c:140
@ X86R_SS
Definition: asm_x86_nz.c:137
@ X86R_CX
Definition: asm_x86_nz.c:104
@ X86R_CR0
Definition: asm_x86_nz.c:142
@ X86R_RDI
Definition: asm_x86_nz.c:126
@ X86R_CR4
Definition: asm_x86_nz.c:146
@ X86R_AL
Definition: asm_x86_nz.c:111
@ X86R_RCX
Definition: asm_x86_nz.c:120
@ X86R_RDX
Definition: asm_x86_nz.c:121
@ X86R_CR1
Definition: asm_x86_nz.c:143
@ X86R_EBX
Definition: asm_x86_nz.c:97
@ X86R_R10
Definition: asm_x86_nz.c:130
@ X86R_EBP
Definition: asm_x86_nz.c:99
@ X86R_DR7
Definition: asm_x86_nz.c:157
@ X86R_R14
Definition: asm_x86_nz.c:134
@ X86R_DR1
Definition: asm_x86_nz.c:151
@ X86R_CR6
Definition: asm_x86_nz.c:148
@ X86R_DR3
Definition: asm_x86_nz.c:153
@ X86R_SP
Definition: asm_x86_nz.c:107
@ X86R_RIP
Definition: asm_x86_nz.c:127
@ X86R_BX
Definition: asm_x86_nz.c:106
@ X86R_BP
Definition: asm_x86_nz.c:108
@ X86R_AH
Definition: asm_x86_nz.c:115
@ X86R_BL
Definition: asm_x86_nz.c:114
@ X86R_DS
Definition: asm_x86_nz.c:138
@ X86R_EAX
Definition: asm_x86_nz.c:94
@ X86R_R12
Definition: asm_x86_nz.c:132
@ X86R_CR2
Definition: asm_x86_nz.c:144
@ X86R_CL
Definition: asm_x86_nz.c:112
@ X86R_CR5
Definition: asm_x86_nz.c:147
@ X86R_RBX
Definition: asm_x86_nz.c:122
@ X86R_UNDEFINED
Definition: asm_x86_nz.c:93
@ X86R_GS
Definition: asm_x86_nz.c:141
@ X86R_ESP
Definition: asm_x86_nz.c:98
@ X86R_DR0
Definition: asm_x86_nz.c:150
@ X86R_DX
Definition: asm_x86_nz.c:105
@ X86R_ECX
Definition: asm_x86_nz.c:95
@ X86R_CS
Definition: asm_x86_nz.c:136
@ X86R_SI
Definition: asm_x86_nz.c:109
@ X86R_DI
Definition: asm_x86_nz.c:110
@ X86R_CH
Definition: asm_x86_nz.c:116
@ X86R_R8
Definition: asm_x86_nz.c:128
@ X86R_ES
Definition: asm_x86_nz.c:139
@ X86R_EDX
Definition: asm_x86_nz.c:96
@ X86R_RBP
Definition: asm_x86_nz.c:124
@ X86R_AX
Definition: asm_x86_nz.c:103
@ X86R_DL
Definition: asm_x86_nz.c:113
@ X86R_DR2
Definition: asm_x86_nz.c:152
@ X86R_R9
Definition: asm_x86_nz.c:129
@ X86R_RAX
Definition: asm_x86_nz.c:119
@ X86R_DR4
Definition: asm_x86_nz.c:154
@ X86R_DR5
Definition: asm_x86_nz.c:155
enum register_t Register

◆ tokentype_t

Enumerator
TT_EOF 
TT_WORD 
TT_NUMBER 
TT_SPECIAL 

Definition at line 85 of file asm_x86_nz.c.

85  {
86  TT_EOF,
87  TT_WORD,
88  TT_NUMBER,
enum tokentype_t x86newTokenType
@ TT_WORD
Definition: asm_x86_nz.c:87
@ TT_NUMBER
Definition: asm_x86_nz.c:88
@ TT_SPECIAL
Definition: asm_x86_nz.c:89
@ TT_EOF
Definition: asm_x86_nz.c:86

Function Documentation

◆ assemble()

static int assemble ( RzAsm a,
RzAsmOp ao,
const char *  str 
)
static

Definition at line 5202 of file asm_x86_nz.c.

5202  {
5203  ut8 __data[32] = { 0 };
5204  ut8 *data = __data;
5205  char op[128];
5206  LookupTable *lt_ptr;
5207  int retval = -1;
5208  Opcode instr = { 0 };
5209 
5210  strncpy(op, str, sizeof(op) - 1);
5211  op[sizeof(op) - 1] = '\0';
5212  parseOpcode(a, op, &instr);
5213  for (lt_ptr = oplookup; strcmp(lt_ptr->mnemonic, "null"); lt_ptr++) {
5214  if (!rz_str_casecmp(instr.mnemonic, lt_ptr->mnemonic)) {
5215  if (lt_ptr->opcode > 0) {
5216  if (!lt_ptr->only_x32 || a->bits != 64) {
5217  ut64 opcode = lt_ptr->opcode;
5218  int i = lt_ptr->size - 1;
5219  for (; i >= 0; i--) {
5220  data[i] = opcode & 0xff;
5221  opcode >>= 8;
5222  }
5223  retval = lt_ptr->size;
5224  }
5225  } else {
5226  if (lt_ptr->opdo) {
5227  if (instr.has_bnd) {
5228  data[0] = 0xf2;
5229  data++;
5230  }
5231  retval = lt_ptr->opdo(a, data, &instr);
5232  // if op supports bnd then the first byte will
5233  // be 0xf2.
5234  if (instr.has_bnd) {
5235  retval++;
5236  }
5237  }
5238  }
5239  break;
5240  }
5241  }
5242  if (retval > 0) {
5243  rz_asm_op_set_buf(ao, __data, retval);
5244  }
5245  free(instr.mnemonic);
5246  return retval;
5247 }
ut8 op
Definition: 6502dis.c:13
RZ_API void rz_asm_op_set_buf(RzAsmOp *op, const ut8 *buf, int len)
Definition: aop.c:83
lzma_index ** i
Definition: index.h:629
LookupTable oplookup[]
Definition: asm_x86_nz.c:4268
static int parseOpcode(RzAsm *a, const char *op, Opcode *out)
Definition: asm_x86_nz.c:5095
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
Definition: str.c:121
#define a(i)
Definition: sha256.c:41
bool has_bnd
Definition: asm_x86_nz.c:195
char * mnemonic
Definition: armass64.c:78
int(* opdo)(RzAsm *, ut8 *, const Opcode *)
Definition: asm_x86_nz.c:4263
char mnemonic[12]
Definition: asm_x86_nz.c:4261
ut64 opcode
Definition: asm_x86_nz.c:4264
int only_x32
Definition: asm_x86_nz.c:4262
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References a, free(), Opcode_t::has_bnd, i, Opcode_t::mnemonic, lookup_t::mnemonic, lookup_t::only_x32, op, lookup_t::opcode, lookup_t::opdo, oplookup, parseOpcode(), rz_asm_op_set_buf(), rz_str_casecmp(), lookup_t::size, cmd_descs_generate::str, and ut64().

◆ endbr32()

static int endbr32 ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 714 of file asm_x86_nz.c.

714  {
715  memcpy(data, "\xf3\x0f\x1e\xfb", 4);
716  return 4;
717 }
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))

References memcpy().

◆ endbr64()

static int endbr64 ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 709 of file asm_x86_nz.c.

709  {
710  memcpy(data, "\xf3\x0f\x1e\xfa", 4);
711  return 4;
712 }

References memcpy().

◆ getnum()

static ut64 getnum ( RzAsm a,
const char *  s 
)
static

Definition at line 5139 of file asm_x86_nz.c.

5139  {
5140  if (!s) {
5141  return 0;
5142  }
5143  if (*s == '$') {
5144  s++;
5145  }
5146  return rz_num_math(a->num, s);
5147 }
static RzSocket * s
Definition: rtr.c:28
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456

References a, rz_num_math(), and s.

Referenced by parse_segment_offset(), parseOperand(), and parseReg().

◆ getsib()

static ut8 getsib ( const ut8  sib)
static

Definition at line 202 of file asm_x86_nz.c.

202  {
203  if (!sib) {
204  return 0;
205  }
206  return (sib & 0x8) ? 3 : getsib((sib << 1) | 1) - 1;
207 }
static ut8 getsib(const ut8 sib)
Definition: asm_x86_nz.c:202

Referenced by opcmov(), opdec(), opinc(), opmov(), and process_1byte_op().

◆ getToken()

static x86newTokenType getToken ( const char *  str,
size_t begin,
size_t end 
)
static

Definition at line 4625 of file asm_x86_nz.c.

4625  {
4626  if (*begin > strlen(str)) {
4627  return TT_EOF;
4628  }
4629  // Skip whitespace
4630  while (begin && str[*begin] && isspace((ut8)str[*begin])) {
4631  ++(*begin);
4632  }
4633 
4634  if (!str[*begin]) { // null byte
4635  *end = *begin;
4636  return TT_EOF;
4637  }
4638  if (isalpha((ut8)str[*begin])) { // word token
4639  *end = *begin;
4640  while (end && str[*end] && isalnum((ut8)str[*end])) {
4641  ++(*end);
4642  }
4643  return TT_WORD;
4644  }
4645  if (isdigit((ut8)str[*begin])) { // number token
4646  *end = *begin;
4647  while (end && isalnum((ut8)str[*end])) { // accept alphanumeric characters, because hex.
4648  ++(*end);
4649  }
4650  return TT_NUMBER;
4651  } else { // special character: [, ], +, *, ...
4652  *end = *begin + 1;
4653  return TT_SPECIAL;
4654  }
4655 }
#define isspace(c)
Definition: safe-ctype.h:141
#define isalpha(c)
Definition: safe-ctype.h:125
#define isdigit(c)
Definition: safe-ctype.h:131
#define isalnum(c)
Definition: safe-ctype.h:127

References test_evm::end, isalnum, isalpha, isdigit, isspace, cmd_descs_generate::str, TT_EOF, TT_NUMBER, TT_SPECIAL, and TT_WORD.

Referenced by parseOperand(), and parseReg().

◆ is_al_reg()

static int is_al_reg ( const Operand op)
static

Definition at line 209 of file asm_x86_nz.c.

209  {
210  if (op->type & OT_MEMORY) {
211  return 0;
212  }
213  if (op->reg == X86R_AL && op->type & OT_BYTE) {
214  return 1;
215  }
216  return 0;
217 }
#define OT_BYTE
Definition: asm_x86_nz.c:49
#define OT_MEMORY
Definition: asm_x86_nz.c:31

References OT_BYTE, OT_MEMORY, and X86R_AL.

Referenced by opadc(), opadd(), opand(), opcmp(), opor(), opsbb(), opsub(), and opxor().

◆ is_debug_or_control()

static bool is_debug_or_control ( Operand  op)
inlinestatic

Definition at line 198 of file asm_x86_nz.c.

198  {
199  return (op.type & OT_REGTYPE) & (OT_CONTROLREG | OT_DEBUGREG);
200 }
#define OT_DEBUGREG
Definition: asm_x86_nz.c:39
#define OT_REGTYPE
Definition: asm_x86_nz.c:43
#define OT_CONTROLREG
Definition: asm_x86_nz.c:38

References OT_CONTROLREG, OT_DEBUGREG, and OT_REGTYPE.

Referenced by opmov().

◆ is_mm_register()

static bool is_mm_register ( const char *  token)
static

Definition at line 4666 of file asm_x86_nz.c.

4666  {
4667  if (!rz_str_ncasecmp("mm", token, 2)) {
4668  const bool parn = token[2] == '(';
4669  if (parn) {
4670  token++;
4671  }
4672  if (isdigit(token[2]) && !isdigit(token[3])) {
4673  int n = token[2];
4674  if (n >= '0' && n <= '7') {
4675  if (parn) {
4676  if (token[3] != ')') {
4677  return false;
4678  }
4679  }
4680  return true;
4681  }
4682  }
4683  }
4684  return false;
4685 }
int n
Definition: mipsasm.c:19
RZ_API int rz_str_ncasecmp(const char *dst, const char *orig, size_t n)
Definition: str.c:129

References isdigit, n, and rz_str_ncasecmp().

Referenced by parseReg().

◆ is_st_register()

static bool is_st_register ( const char *  token)
static

Definition at line 4687 of file asm_x86_nz.c.

4687  {
4688  if (!rz_str_ncasecmp("st", token, 2)) {
4689  const bool parn = token[2] == '(';
4690  if (parn) {
4691  token++;
4692  }
4693  if (isdigit(token[2]) && !isdigit(token[3])) {
4694  int n = token[2];
4695  if (n >= '0' && n <= '7') {
4696  if (parn) {
4697  if (token[3] != ')') {
4698  return false;
4699  }
4700  }
4701  return true;
4702  }
4703  }
4704  }
4705  return false;
4706 }

References isdigit, n, and rz_str_ncasecmp().

Referenced by parseReg().

◆ is_xmm_register()

static bool is_xmm_register ( const char *  token)
static

Definition at line 4657 of file asm_x86_nz.c.

4657  {
4658  // check xmm0..xmm15
4659  if (!rz_str_ncasecmp("xmm", token, 3)) {
4660  int n = atoi(token + 3);
4661  return (n >= 0 && n <= 15);
4662  }
4663  return false;
4664 }

References n, and rz_str_ncasecmp().

Referenced by parseReg().

◆ opaam()

static int opaam ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1042 of file asm_x86_nz.c.

1042  {
1044  int l = 0;
1045  int immediate = op->operands[0].immediate * op->operands[0].sign;
1046  data[l++] = 0xd4;
1047  if (immediate == 0) {
1048  data[l++] = 0x0a;
1049  } else if (immediate < 256 && immediate > -129) {
1050  data[l++] = immediate;
1051  }
1052  return l;
1053 }
#define is_valid_registers(op)
Definition: asm_x86_nz.c:79

References is_valid_registers.

◆ opadc()

static int opadc ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 561 of file asm_x86_nz.c.

561  {
562  if (op->operands[1].type & OT_CONSTANT) {
563  if (op->operands[0].type & OT_GPREG &&
564  op->operands[0].type & OT_WORD) {
565  return process_16bit_group_1(a, data, op, 0x10);
566  }
567  if (!is_al_reg(&op->operands[0])) {
568  return process_group_1(a, data, op);
569  }
570  }
571  return process_1byte_op(a, data, op, 0x10);
572 }
#define OT_GPREG
Definition: asm_x86_nz.c:33
static int process_16bit_group_1(RzAsm *a, ut8 *data, const Opcode *op, int op1)
Definition: asm_x86_nz.c:221
static int process_group_1(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:246
static int is_al_reg(const Operand *op)
Definition: asm_x86_nz.c:209
#define OT_WORD
Definition: asm_x86_nz.c:50
#define OT_CONSTANT
Definition: asm_x86_nz.c:32
static int process_1byte_op(RzAsm *a, ut8 *data, const Opcode *op, int op1)
Definition: asm_x86_nz.c:414

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ opadd()

static int opadd ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 574 of file asm_x86_nz.c.

574  {
575  if (op->operands[1].type & OT_CONSTANT) {
576  if (op->operands[0].type & OT_GPREG &&
577  op->operands[0].type & OT_WORD) {
578  return process_16bit_group_1(a, data, op, 0x00);
579  }
580  if (!is_al_reg(&op->operands[0])) {
581  return process_group_1(a, data, op);
582  }
583  }
584  return process_1byte_op(a, data, op, 0x00);
585 }

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ opand()

static int opand ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 587 of file asm_x86_nz.c.

587  {
588  if (op->operands[1].type & OT_CONSTANT) {
589  if (op->operands[0].type & OT_GPREG &&
590  op->operands[0].type & OT_WORD) {
591  return process_16bit_group_1(a, data, op, 0x20);
592  }
593  if (!is_al_reg(&op->operands[0])) {
594  return process_group_1(a, data, op);
595  }
596  }
597  return process_1byte_op(a, data, op, 0x20);
598 }

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ opbs()

static int opbs ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 765 of file asm_x86_nz.c.

765  {
766  int l = 0;
767  if (a->bits >= 32 && op->operands[1].type & OT_MEMORY && op->operands[1].reg_size & OT_WORD) {
768  return -1;
769  }
770  if (!(op->operands[1].type & OT_MEMORY) &&
771  !((op->operands[0].type & ALL_SIZE) == (op->operands[1].type & ALL_SIZE))) {
772  return -1;
773  }
774  if (op->operands[0].type & OT_GPREG && !(op->operands[0].type & OT_MEMORY)) {
775  if (a->bits == 64) {
776  if (op->operands[1].type & OT_MEMORY &&
777  op->operands[1].reg_size & OT_DWORD) {
778  data[l++] = 0x67;
779  }
780  if (op->operands[0].type & OT_WORD) {
781  data[l++] = 0x66;
782  }
783  if (op->operands[0].type & OT_QWORD) {
784  data[l++] = 0x48;
785  }
786  } else if (op->operands[0].type & OT_WORD) {
787  data[l++] = 0x66;
788  }
789  data[l++] = 0x0f;
790  if (!strcmp(op->mnemonic, "bsf")) {
791  data[l++] = 0xbc;
792  } else {
793  data[l++] = 0xbd;
794  }
795  if (op->operands[1].type & OT_GPREG && !(op->operands[1].type & OT_MEMORY)) {
796  data[l] = 0xc0;
797  } else if (!(op->operands[1].type & OT_MEMORY)) {
798  return -1;
799  }
800  data[l] += op->operands[0].reg << 3;
801  data[l++] += op->operands[1].reg;
802  }
803  return l;
804 }
#define OT_DWORD
Definition: asm_x86_nz.c:51
#define OT_QWORD
Definition: asm_x86_nz.c:52
#define ALL_SIZE
Definition: asm_x86_nz.c:56

References a, ALL_SIZE, OT_DWORD, OT_GPREG, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opbswap()

static int opbswap ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 806 of file asm_x86_nz.c.

806  {
807  int l = 0;
808  if (op->operands[0].type & OT_REGALL) {
810  if (op->operands[0].reg == X86R_UNDEFINED) {
811  return -1;
812  }
813 
814  if (op->operands[0].type & OT_QWORD) {
815  if (op->operands[0].extended) {
816  data[l++] = 0x49;
817  } else {
818  data[l++] = 0x48;
819  }
820  data[l++] = 0x0f;
821  data[l++] = 0xc8 + op->operands[0].reg;
822  } else if (op->operands[0].type & OT_DWORD) {
823  if (op->operands[0].extended) {
824  data[l++] = 0x41;
825  }
826  data[l++] = 0x0f;
827  data[l++] = 0xc8 + op->operands[0].reg;
828  } else {
829  return -1;
830  }
831  }
832  return l;
833 }
#define OT_REGALL
Definition: asm_x86_nz.c:28

References is_valid_registers, OT_DWORD, OT_QWORD, OT_REGALL, and X86R_UNDEFINED.

◆ opcall()

static int opcall ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 835 of file asm_x86_nz.c.

835  {
837  int l = 0;
838  int immediate = 0;
839  int offset = 0;
840  int mod = 0;
841 
842  if (op->operands[0].type & OT_GPREG) {
843  if (op->operands[0].reg == X86R_UNDEFINED) {
844  return -1;
845  }
846  if (a->bits == 64 && op->operands[0].extended) {
847  data[l++] = 0x41;
848  }
849  data[l++] = 0xff;
850  mod = 3;
851  data[l++] = mod << 6 | 2 << 3 | op->operands[0].reg;
852  } else if (op->operands[0].type & OT_MEMORY) {
853  if (op->operands[0].regs[0] == X86R_UNDEFINED) {
854  return -1;
855  }
856  data[l++] = 0xff;
857  offset = op->operands[0].offset * op->operands[0].offset_sign;
858  if (offset) {
859  mod = 1;
860  if (offset > 127 || offset < -128) {
861  mod = 2;
862  }
863  }
864  data[l++] = mod << 6 | 2 << 3 | op->operands[0].regs[0];
865  if (mod) {
866  data[l++] = offset;
867  if (mod == 2) {
868  data[l++] = offset >> 8;
869  data[l++] = offset >> 16;
870  data[l++] = offset >> 24;
871  }
872  }
873  } else {
874  ut64 instr_offset = a->pc;
875  data[l++] = 0xe8;
876  immediate = op->operands[0].immediate * op->operands[0].sign;
877  immediate -= instr_offset + 5;
878  data[l++] = immediate;
879  data[l++] = immediate >> 8;
880  data[l++] = immediate >> 16;
881  data[l++] = immediate >> 24;
882  }
883  return l;
884 }
int mod(int a, int b)
Definition: crypto_rot.c:8
voidpf uLong offset
Definition: ioapi.h:144

References a, is_valid_registers, mod(), OT_GPREG, OT_MEMORY, ut64(), and X86R_UNDEFINED.

◆ opcdqe()

static int opcdqe ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2871 of file asm_x86_nz.c.

2871  {
2873  int l = 0;
2874  if (a->bits == 64) {
2875  data[l++] = 0x48;
2876  }
2877  data[l++] = 0x98;
2878  return l;
2879 }

References a, and is_valid_registers.

◆ opclflush()

static int opclflush ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1442 of file asm_x86_nz.c.

1442  {
1444  int l = 0;
1445  int offset = 0;
1446  int mod_byte = 0;
1447 
1448  if (op->operands[0].type & OT_MEMORY) {
1449  data[l++] = 0x0f;
1450  data[l++] = 0xae;
1451  offset = op->operands[0].offset * op->operands[0].offset_sign;
1452  if (offset) {
1454  mod_byte = 2;
1455  } else {
1456  mod_byte = 1;
1457  }
1458  }
1459  data[l++] = (mod_byte << 6) | (7 << 3) | op->operands[0].regs[0];
1460  if (mod_byte) {
1461  data[l++] = offset;
1462  if (mod_byte == 2) {
1463  data[l++] = offset >> 8;
1464  data[l++] = offset >> 16;
1465  data[l++] = offset >> 24;
1466  }
1467  }
1468  }
1469  return l;
1470 }
#define ST8_MAX

References is_valid_registers, OT_MEMORY, and ST8_MAX.

◆ opcmov()

static int opcmov ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 886 of file asm_x86_nz.c.

886  {
888  int l = 0;
889  int mod_byte = 0;
890  int offset = 0;
891 
892  if (op->operands[0].type & OT_MEMORY ||
893  op->operands[1].type & OT_CONSTANT) {
894  return -1;
895  }
896 
897  data[l++] = 0x0f;
898  char *cmov = op->mnemonic + 4;
899  if (!strcmp(cmov, "o")) {
900  data[l++] = 0x40;
901  } else if (!strcmp(cmov, "no")) {
902  data[l++] = 0x41;
903  } else if (!strcmp(cmov, "b") ||
904  !strcmp(cmov, "c") ||
905  !strcmp(cmov, "nae")) {
906  data[l++] = 0x42;
907  } else if (!strcmp(cmov, "ae") ||
908  !strcmp(cmov, "nb") ||
909  !strcmp(cmov, "nc")) {
910  data[l++] = 0x43;
911  } else if (!strcmp(cmov, "e") ||
912  !strcmp(cmov, "z")) {
913  data[l++] = 0x44;
914  } else if (!strcmp(cmov, "ne") ||
915  !strcmp(cmov, "nz")) {
916  data[l++] = 0x45;
917  } else if (!strcmp(cmov, "be") ||
918  !strcmp(cmov, "na")) {
919  data[l++] = 0x46;
920  } else if (!strcmp(cmov, "a") ||
921  !strcmp(cmov, "nbe")) {
922  data[l++] = 0x47;
923  } else if (!strcmp(cmov, "s")) {
924  data[l++] = 0x48;
925  } else if (!strcmp(cmov, "ns")) {
926  data[l++] = 0x49;
927  } else if (!strcmp(cmov, "p") ||
928  !strcmp(cmov, "pe")) {
929  data[l++] = 0x4a;
930  } else if (!strcmp(cmov, "np") ||
931  !strcmp(cmov, "po")) {
932  data[l++] = 0x4b;
933  } else if (!strcmp(cmov, "l") ||
934  !strcmp(cmov, "nge")) {
935  data[l++] = 0x4c;
936  } else if (!strcmp(cmov, "ge") ||
937  !strcmp(cmov, "nl")) {
938  data[l++] = 0x4d;
939  } else if (!strcmp(cmov, "le") ||
940  !strcmp(cmov, "ng")) {
941  data[l++] = 0x4e;
942  } else if (!strcmp(cmov, "g") ||
943  !strcmp(cmov, "nle")) {
944  data[l++] = 0x4f;
945  }
946 
947  if (op->operands[0].type & OT_REGALL) {
948  if (op->operands[1].type & OT_MEMORY) {
949  if (op->operands[1].scale[0] > 1) {
950  if (op->operands[1].regs[1] != X86R_UNDEFINED) {
951  data[l++] = op->operands[0].reg << 3 | 4;
952  data[l++] = getsib(op->operands[1].scale[0]) << 6 |
953  op->operands[1].regs[0] << 3 |
954  op->operands[1].regs[1];
955  return l;
956  }
957  offset = op->operands[1].offset * op->operands[1].offset_sign;
958 
959  if (op->operands[1].scale[0] == 2 && offset) {
960  data[l++] = 0x40 | op->operands[0].reg << 3 | 4; // 4 = SIB
961  } else {
962  data[l++] = op->operands[0].reg << 3 | 4; // 4 = SIB
963  }
964 
965  if (op->operands[1].scale[0] == 2) {
966  data[l++] = op->operands[1].regs[0] << 3 | op->operands[1].regs[0];
967 
968  } else {
969  data[l++] = getsib(op->operands[1].scale[0]) << 6 |
970  op->operands[1].regs[0] << 3 | 5;
971  }
972 
973  if (offset) {
974  data[l++] = offset;
976  data[l++] = offset >> 8;
977  data[l++] = offset >> 16;
978  data[l++] = offset >> 24;
979  }
980  }
981  return l;
982  }
983  if (op->operands[1].regs[1] != X86R_UNDEFINED) {
984  data[l++] = op->operands[0].reg << 3 | 4;
985  data[l++] = op->operands[1].regs[1] << 3 | op->operands[1].regs[0];
986  return l;
987  }
988 
989  offset = op->operands[1].offset * op->operands[1].offset_sign;
990  if (op->operands[1].offset || op->operands[1].regs[0] == X86R_EBP) {
991  mod_byte = 1;
992  }
994  mod_byte = 2;
995  }
996 
997  data[l++] = mod_byte << 6 | op->operands[0].reg << 3 | op->operands[1].regs[0];
998 
999  if (mod_byte) {
1000  data[l++] = offset;
1001  if (mod_byte == 2) {
1002  data[l++] = offset >> 8;
1003  data[l++] = offset >> 16;
1004  data[l++] = offset >> 24;
1005  }
1006  }
1007  } else {
1008  data[l++] = 0xc0 | op->operands[0].reg << 3 | op->operands[1].reg;
1009  }
1010  }
1011 
1012  return l;
1013 }

References getsib(), is_valid_registers, OT_CONSTANT, OT_MEMORY, OT_REGALL, ST8_MAX, X86R_EBP, and X86R_UNDEFINED.

◆ opcmp()

static int opcmp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 600 of file asm_x86_nz.c.

600  {
601  if (op->operands[1].type & OT_CONSTANT) {
602  if (op->operands[0].type & OT_GPREG &&
603  op->operands[0].type & OT_WORD) {
604  return process_16bit_group_1(a, data, op, 0x38);
605  }
606  if (!is_al_reg(&op->operands[0])) {
607  return process_group_1(a, data, op);
608  }
609  }
610  return process_1byte_op(a, data, op, 0x38);
611 }

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ opdec()

static int opdec ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1055 of file asm_x86_nz.c.

1055  {
1056  if (op->operands[1].type) {
1057  RZ_LOG_ERROR("assembler: x86.nz: %s: invalid operands\n", op->mnemonic);
1058  return -1;
1059  }
1061  int l = 0;
1062  int size = op->operands[0].type & ALL_SIZE;
1063  if (op->operands[0].explicit_size) {
1064  size = op->operands[0].dest_size;
1065  }
1066 
1067  if (size & OT_WORD) {
1068  data[l++] = 0x66;
1069  }
1070 
1071  // rex prefix
1072  int rex = 1 << 6;
1073  bool use_rex = false;
1074  if (size & OT_QWORD) { // W field
1075  use_rex = true;
1076  rex |= 1 << 3;
1077  }
1078  if (op->operands[0].extended) { // B field
1079  use_rex = true;
1080  rex |= 1;
1081  }
1082 
1083  // opcode selection
1084  int opcode;
1085  if (size & OT_BYTE) {
1086  opcode = 0xfe;
1087  } else {
1088  opcode = 0xff;
1089  }
1090 
1091  if (!(op->operands[0].type & OT_MEMORY)) {
1092  if (use_rex) {
1093  data[l++] = rex;
1094  }
1095  if (a->bits > 32 || size & OT_BYTE) {
1096  data[l++] = opcode;
1097  }
1098  if (a->bits == 32 && size & (OT_DWORD | OT_WORD)) {
1099  data[l++] = 0x48 | op->operands[0].reg;
1100  } else {
1101  data[l++] = 0xc8 | op->operands[0].reg;
1102  }
1103  return l;
1104  }
1105 
1106  // modrm and SIB selection
1107  bool rip_rel = op->operands[0].regs[0] == X86R_RIP;
1108  int offset = op->operands[0].offset * op->operands[0].offset_sign;
1109  int modrm = 0;
1110  int mod;
1111  int reg = 0;
1112  int rm;
1113  bool use_sib = false;
1114  int sib = 0;
1115  // mod
1116  if (offset == 0) {
1117  mod = 0;
1118  } else if (offset < 128 && offset > -129) {
1119  mod = 1;
1120  } else {
1121  mod = 2;
1122  }
1123 
1124  if (op->operands[0].regs[0] & OT_WORD) {
1125  if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == X86R_SI) {
1126  rm = B0000;
1127  } else if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == X86R_DI) {
1128  rm = B0001;
1129  } else if (op->operands[0].regs[0] == X86R_BP && op->operands[0].regs[1] == X86R_SI) {
1130  rm = B0010;
1131  } else if (op->operands[0].regs[0] == X86R_BP && op->operands[0].regs[1] == X86R_DI) {
1132  rm = B0011;
1133  } else if (op->operands[0].regs[0] == X86R_SI && op->operands[0].regs[1] == -1) {
1134  rm = B0100;
1135  } else if (op->operands[0].regs[0] == X86R_DI && op->operands[0].regs[1] == -1) {
1136  rm = B0101;
1137  } else if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == -1) {
1138  rm = B0111;
1139  } else {
1140  // TODO allow for displacement only when parser is reworked
1141  return -1;
1142  }
1143  modrm = (mod << 6) | (reg << 3) | rm;
1144  } else {
1145  // rm
1146  if (op->operands[0].extended) {
1147  rm = op->operands[0].reg;
1148  } else {
1149  rm = op->operands[0].regs[0];
1150  }
1151  //[epb] alone is illegal, so we need to fake a [ebp+0]
1152  if (rm == 5 && mod == 0) {
1153  mod = 1;
1154  }
1155 
1156  // sib
1157  int index = op->operands[0].regs[1];
1158  int scale = getsib(op->operands[0].scale[1]);
1159  if (index != -1) {
1160  use_sib = true;
1161  sib = (scale << 6) | (index << 3) | rm;
1162  } else if (rm == 4) {
1163  use_sib = true;
1164  sib = 0x24;
1165  }
1166  if (use_sib) {
1167  rm = B0100;
1168  }
1169  if (rip_rel) {
1170  modrm = (B0000 << 6) | (reg << 3) | B0101;
1171  sib = (scale << 6) | (B0100 << 3) | B0101;
1172  } else {
1173  modrm = (mod << 6) | (reg << 3) | rm;
1174  }
1175  modrm |= 1 << 3;
1176  }
1177 
1178  if (use_rex) {
1179  data[l++] = rex;
1180  }
1181  data[l++] = opcode;
1182  data[l++] = modrm;
1183  if (use_sib) {
1184  data[l++] = sib;
1185  }
1186  // offset
1187  if (mod == 1) {
1188  data[l++] = offset;
1189  } else if (op->operands[0].regs[0] & OT_WORD && mod == 2) {
1190  data[l++] = offset;
1191  data[l++] = offset >> 8;
1192  } else if (mod == 2 || rip_rel) {
1193  data[l++] = offset;
1194  data[l++] = offset >> 8;
1195  data[l++] = offset >> 16;
1196  data[l++] = offset >> 24;
1197  }
1198 
1199  return l;
1200 }
voidpf void uLong size
Definition: ioapi.h:138
#define reg(n)
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define B0010
#define B0111
#define B0100
#define B0011
#define B0001
#define B0000
#define B0101

References a, ALL_SIZE, B0000, B0001, B0010, B0011, B0100, B0101, B0111, getsib(), is_valid_registers, mod(), OT_BYTE, OT_DWORD, OT_MEMORY, OT_QWORD, OT_WORD, reg, RZ_LOG_ERROR, X86R_BP, X86R_BX, X86R_DI, X86R_RIP, and X86R_SI.

◆ opdiv()

static int opdiv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1231 of file asm_x86_nz.c.

1231  {
1233  int l = 0;
1234 
1235  if (op->operands[0].type & OT_QWORD) {
1236  data[l++] = 0x48;
1237  }
1238  switch (op->operands_count) {
1239  case 1:
1240  if (op->operands[0].type & OT_WORD) {
1241  data[l++] = 0x66;
1242  }
1243  if (op->operands[0].type & OT_BYTE) {
1244  data[l++] = 0xf6;
1245  } else {
1246  data[l++] = 0xf7;
1247  }
1248  if (op->operands[0].type & OT_MEMORY) {
1249  data[l++] = 0x30 | op->operands[0].regs[0];
1250  } else {
1251  data[l++] = 0xf0 | op->operands[0].reg;
1252  }
1253  break;
1254  default:
1255  return -1;
1256  }
1257  return l;
1258 }

References is_valid_registers, OT_BYTE, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opfadd()

static int opfadd ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3068 of file asm_x86_nz.c.

3068  {
3069  int l = 0;
3070  switch (op->operands_count) {
3071  case 1:
3072  if (op->operands[0].type & OT_MEMORY) {
3073  if (op->operands[0].type & OT_QWORD) {
3074  data[l++] = 0xdc;
3075  data[l++] = 0x00 | op->operands[0].regs[0];
3076  } else if (op->operands[0].type & OT_DWORD) {
3077  data[l++] = 0xd8;
3078  data[l++] = 0x00 | op->operands[0].regs[0];
3079  } else {
3080  return -1;
3081  }
3082  } else {
3083  return -1;
3084  }
3085  break;
3086  case 2:
3087  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
3088  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
3089  data[l++] = 0xd8;
3090  data[l++] = 0xc0 | op->operands[1].reg;
3091  } else if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3092  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3093  data[l++] = 0xdc;
3094  data[l++] = 0xc0 | op->operands[0].reg;
3095  } else {
3096  return -1;
3097  }
3098  break;
3099  default:
3100  return -1;
3101  }
3102  return l;
3103 }
#define OT_FPUREG
Definition: asm_x86_nz.c:35

References OT_DWORD, OT_FPUREG, OT_MEMORY, OT_QWORD, and OT_REGALL.

◆ opfaddp()

static int opfaddp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3022 of file asm_x86_nz.c.

3022  {
3023  int l = 0;
3024  switch (op->operands_count) {
3025  case 2:
3026  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3027  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3028  data[l++] = 0xde;
3029  data[l++] = 0xc0 | op->operands[0].reg;
3030  } else {
3031  return -1;
3032  }
3033  break;
3034  case 0:
3035  data[l++] = 0xde;
3036  data[l++] = 0xc1;
3037  break;
3038  default:
3039  return -1;
3040  }
3041  return l;
3042 }

References OT_FPUREG, and OT_REGALL.

◆ opfbld()

static int opfbld ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3215 of file asm_x86_nz.c.

3215  {
3216  int l = 0;
3217  switch (op->operands_count) {
3218  case 1:
3219  if (op->operands[0].type & OT_MEMORY &&
3220  op->operands[0].type & OT_TBYTE) {
3221  data[l++] = 0xdf;
3222  data[l++] = 0x20 | op->operands[0].regs[0];
3223  } else {
3224  return -1;
3225  }
3226  break;
3227  default:
3228  return -1;
3229  }
3230  return l;
3231 }
#define OT_TBYTE
Definition: asm_x86_nz.c:54

References OT_MEMORY, and OT_TBYTE.

◆ opfbstp()

static int opfbstp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3233 of file asm_x86_nz.c.

3233  {
3234  int l = 0;
3235  switch (op->operands_count) {
3236  case 1:
3237  if (op->operands[0].type & OT_MEMORY &&
3238  op->operands[0].type & OT_TBYTE) {
3239  data[l++] = 0xdf;
3240  data[l++] = 0x30 | op->operands[0].regs[0];
3241  } else {
3242  return -1;
3243  }
3244  break;
3245  default:
3246  return -1;
3247  }
3248  return l;
3249 }

References OT_MEMORY, and OT_TBYTE.

◆ opfcmov()

static int opfcmov ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2881 of file asm_x86_nz.c.

2881  {
2882  int l = 0;
2883  char *fcmov = op->mnemonic + strlen("fcmov");
2884  switch (op->operands_count) {
2885  case 2:
2886  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
2887  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
2888  if (!strcmp(fcmov, "b")) {
2889  data[l++] = 0xda;
2890  data[l++] = 0xc0 | op->operands[1].reg;
2891  } else if (!strcmp(fcmov, "e")) {
2892  data[l++] = 0xda;
2893  data[l++] = 0xc8 | op->operands[1].reg;
2894  } else if (!strcmp(fcmov, "be")) {
2895  data[l++] = 0xda;
2896  data[l++] = 0xd0 | op->operands[1].reg;
2897  } else if (!strcmp(fcmov, "u")) {
2898  data[l++] = 0xda;
2899  data[l++] = 0xd8 | op->operands[1].reg;
2900  } else if (!strcmp(fcmov, "nb")) {
2901  data[l++] = 0xdb;
2902  data[l++] = 0xc0 | op->operands[1].reg;
2903  } else if (!strcmp(fcmov, "ne")) {
2904  data[l++] = 0xdb;
2905  data[l++] = 0xc8 | op->operands[1].reg;
2906  } else if (!strcmp(fcmov, "nbe")) {
2907  data[l++] = 0xdb;
2908  data[l++] = 0xd0 | op->operands[1].reg;
2909  } else if (!strcmp(fcmov, "nu")) {
2910  data[l++] = 0xdb;
2911  data[l++] = 0xd8 | op->operands[1].reg;
2912  } else {
2913  return -1;
2914  }
2915  } else {
2916  return -1;
2917  }
2918  break;
2919  default:
2920  return -1;
2921  }
2922  return l;
2923 }

References OT_FPUREG, and OT_REGALL.

◆ opfdiv()

static int opfdiv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3400 of file asm_x86_nz.c.

3400  {
3401  int l = 0;
3402  switch (op->operands_count) {
3403  case 1:
3404  if (op->operands[0].type & OT_MEMORY) {
3405  if (op->operands[0].type & OT_DWORD) {
3406  data[l++] = 0xd8;
3407  data[l++] = 0x30 | op->operands[0].regs[0];
3408  } else if (op->operands[0].type & OT_QWORD) {
3409  data[l++] = 0xdc;
3410  data[l++] = 0x30 | op->operands[0].regs[0];
3411  } else {
3412  return -1;
3413  }
3414  } else {
3415  return -1;
3416  }
3417  break;
3418  case 2:
3419  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
3420  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
3421  data[l++] = 0xd8;
3422  data[l++] = 0xf0 | op->operands[1].reg;
3423  } else if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3424  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3425  data[l++] = 0xdc;
3426  data[l++] = 0xf8 | op->operands[0].reg;
3427  } else {
3428  return -1;
3429  }
3430  break;
3431  default:
3432  return -1;
3433  }
3434  return l;
3435 }

References OT_DWORD, OT_FPUREG, OT_MEMORY, OT_QWORD, and OT_REGALL.

◆ opfdivp()

static int opfdivp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3437 of file asm_x86_nz.c.

3437  {
3438  int l = 0;
3439  switch (op->operands_count) {
3440  case 0:
3441  data[l++] = 0xde;
3442  data[l++] = 0xf9;
3443  break;
3444  case 2:
3445  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3446  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3447  data[l++] = 0xde;
3448  data[l++] = 0xf8 | op->operands[0].reg;
3449  } else {
3450  return -1;
3451  }
3452  break;
3453  default:
3454  return -1;
3455  }
3456  return l;
3457 }

References OT_FPUREG, and OT_REGALL.

◆ opfdivr()

static int opfdivr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3483 of file asm_x86_nz.c.

3483  {
3484  int l = 0;
3485  switch (op->operands_count) {
3486  case 1:
3487  if (op->operands[0].type & OT_MEMORY) {
3488  if (op->operands[0].type & OT_DWORD) {
3489  data[l++] = 0xd8;
3490  data[l++] = 0x38 | op->operands[0].regs[0];
3491  } else if (op->operands[0].type & OT_QWORD) {
3492  data[l++] = 0xdc;
3493  data[l++] = 0x38 | op->operands[0].regs[0];
3494  } else {
3495  return -1;
3496  }
3497  } else {
3498  return -1;
3499  }
3500  break;
3501  case 2:
3502  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
3503  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
3504  data[l++] = 0xd8;
3505  data[l++] = 0xf8 | op->operands[1].reg;
3506  } else if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3507  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3508  data[l++] = 0xdc;
3509  data[l++] = 0xf0 | op->operands[0].reg;
3510  } else {
3511  return -1;
3512  }
3513  break;
3514  default:
3515  return -1;
3516  }
3517  return l;
3518 }

References OT_DWORD, OT_FPUREG, OT_MEMORY, OT_QWORD, and OT_REGALL.

◆ opfdivrp()

static int opfdivrp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3520 of file asm_x86_nz.c.

3520  {
3521  int l = 0;
3522  switch (op->operands_count) {
3523  case 0:
3524  data[l++] = 0xde;
3525  data[l++] = 0xf1;
3526  break;
3527  case 2:
3528  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3529  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3530  data[l++] = 0xde;
3531  data[l++] = 0xf0 | op->operands[0].reg;
3532  } else {
3533  return -1;
3534  }
3535  break;
3536  default:
3537  return -1;
3538  }
3539  return l;
3540 }

References OT_FPUREG, and OT_REGALL.

◆ opffree()

static int opffree ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2925 of file asm_x86_nz.c.

2925  {
2926  int l = 0;
2927  switch (op->operands_count) {
2928  case 1:
2929  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL) {
2930  data[l++] = 0xdd;
2931  data[l++] = 0xc0 | op->operands[0].reg;
2932  } else {
2933  return -1;
2934  }
2935  break;
2936  default:
2937  return -1;
2938  }
2939  return l;
2940 }

References OT_FPUREG, and OT_REGALL.

◆ opfiadd()

static int opfiadd ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3044 of file asm_x86_nz.c.

3044  {
3045  int l = 0;
3046  switch (op->operands_count) {
3047  case 1:
3048  if (op->operands[0].type & OT_MEMORY) {
3049  if (op->operands[0].type & OT_WORD) {
3050  data[l++] = 0xde;
3051  data[l++] = 0x00 | op->operands[0].regs[0];
3052  } else if (op->operands[0].type & OT_DWORD) {
3053  data[l++] = 0xda;
3054  data[l++] = 0x00 | op->operands[0].regs[0];
3055  } else {
3056  return -1;
3057  }
3058  } else {
3059  return -1;
3060  }
3061  break;
3062  default:
3063  return -1;
3064  }
3065  return l;
3066 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opficom()

static int opficom ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3105 of file asm_x86_nz.c.

3105  {
3106  int l = 0;
3107  switch (op->operands_count) {
3108  case 1:
3109  if (op->operands[0].type & OT_MEMORY) {
3110  if (op->operands[0].type & OT_WORD) {
3111  data[l++] = 0xde;
3112  data[l++] = 0x10 | op->operands[0].regs[0];
3113  } else if (op->operands[0].type & OT_DWORD) {
3114  data[l++] = 0xda;
3115  data[l++] = 0x10 | op->operands[0].regs[0];
3116  } else {
3117  return -1;
3118  }
3119  } else {
3120  return -1;
3121  }
3122  break;
3123  default:
3124  return -1;
3125  }
3126  return l;
3127 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opficomp()

static int opficomp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3129 of file asm_x86_nz.c.

3129  {
3130  int l = 0;
3131  switch (op->operands_count) {
3132  case 1:
3133  if (op->operands[0].type & OT_MEMORY) {
3134  if (op->operands[0].type & OT_WORD) {
3135  data[l++] = 0xde;
3136  data[l++] = 0x18 | op->operands[0].regs[0];
3137  } else if (op->operands[0].type & OT_DWORD) {
3138  data[l++] = 0xda;
3139  data[l++] = 0x18 | op->operands[0].regs[0];
3140  } else {
3141  return -1;
3142  }
3143  } else {
3144  return -1;
3145  }
3146  break;
3147  default:
3148  return -1;
3149  }
3150  return l;
3151 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfidiv()

static int opfidiv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3459 of file asm_x86_nz.c.

3459  {
3460  int l = 0;
3461  switch (op->operands_count) {
3462  case 1:
3463  if (op->operands[0].type & OT_MEMORY) {
3464  if (op->operands[0].type & OT_DWORD) {
3465  data[l++] = 0xda;
3466  data[l++] = 0x30 | op->operands[0].regs[0];
3467  } else if (op->operands[0].type & OT_WORD) {
3468  data[l++] = 0xde;
3469  data[l++] = 0x30 | op->operands[0].regs[0];
3470  } else {
3471  return -1;
3472  }
3473  } else {
3474  return -1;
3475  }
3476  break;
3477  default:
3478  return -1;
3479  }
3480  return l;
3481 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfidivr()

static int opfidivr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3542 of file asm_x86_nz.c.

3542  {
3543  int l = 0;
3544  switch (op->operands_count) {
3545  case 1:
3546  if (op->operands[0].type & OT_MEMORY) {
3547  if (op->operands[0].type & OT_DWORD) {
3548  data[l++] = 0xda;
3549  data[l++] = 0x38 | op->operands[0].regs[0];
3550  } else if (op->operands[0].type & OT_WORD) {
3551  data[l++] = 0xde;
3552  data[l++] = 0x38 | op->operands[0].regs[0];
3553  } else {
3554  return -1;
3555  }
3556  } else {
3557  return -1;
3558  }
3559  break;
3560  default:
3561  return -1;
3562  }
3563  return l;
3564 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfild()

static int opfild ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3153 of file asm_x86_nz.c.

3153  {
3154  int l = 0;
3155  switch (op->operands_count) {
3156  case 1:
3157  if (op->operands[0].type & OT_MEMORY) {
3158  if (op->operands[0].type & OT_WORD) {
3159  data[l++] = 0xdf;
3160  data[l++] = 0x00 | op->operands[0].regs[0];
3161  } else if (op->operands[0].type & OT_DWORD) {
3162  data[l++] = 0xdb;
3163  data[l++] = 0x00 | op->operands[0].regs[0];
3164  } else if (op->operands[0].type & OT_QWORD) {
3165  data[l++] = 0xdf;
3166  data[l++] = 0x28 | op->operands[0].regs[0];
3167  } else {
3168  return -1;
3169  }
3170  } else {
3171  return -1;
3172  }
3173  break;
3174  default:
3175  return -1;
3176  }
3177  return l;
3178 }

References OT_DWORD, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opfimul()

static int opfimul ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3625 of file asm_x86_nz.c.

3625  {
3626  int l = 0;
3627  switch (op->operands_count) {
3628  case 1:
3629  if (op->operands[0].type & OT_MEMORY) {
3630  if (op->operands[0].type & OT_DWORD) {
3631  data[l++] = 0xda;
3632  data[l++] = 0x08 | op->operands[0].regs[0];
3633  } else if (op->operands[0].type & OT_WORD) {
3634  data[l++] = 0xde;
3635  data[l++] = 0x08 | op->operands[0].regs[0];
3636  } else {
3637  return -1;
3638  }
3639  } else {
3640  return -1;
3641  }
3642  break;
3643  default:
3644  return -1;
3645  }
3646  return l;
3647 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfist()

static int opfist ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3287 of file asm_x86_nz.c.

3287  {
3288  int l = 0;
3289  switch (op->operands_count) {
3290  case 1:
3291  if (op->operands[0].type & OT_MEMORY) {
3292  if (op->operands[0].type & OT_WORD) {
3293  data[l++] = 0xdf;
3294  data[l++] = 0x10 | op->operands[0].regs[0];
3295  } else if (op->operands[0].type & OT_DWORD) {
3296  data[l++] = 0xdb;
3297  data[l++] = 0x10 | op->operands[0].regs[0];
3298  } else {
3299  return -1;
3300  }
3301  } else {
3302  return -1;
3303  }
3304  break;
3305  default:
3306  return -1;
3307  }
3308  return l;
3309 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfistp()

static int opfistp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3311 of file asm_x86_nz.c.

3311  {
3312  int l = 0;
3313  switch (op->operands_count) {
3314  case 1:
3315  if (op->operands[0].type & OT_MEMORY) {
3316  if (op->operands[0].type & OT_WORD) {
3317  data[l++] = 0xdf;
3318  data[l++] = 0x18 | op->operands[0].regs[0];
3319  } else if (op->operands[0].type & OT_DWORD) {
3320  data[l++] = 0xdb;
3321  data[l++] = 0x18 | op->operands[0].regs[0];
3322  } else if (op->operands[0].type & OT_QWORD) {
3323  data[l++] = 0xdf;
3324  data[l++] = 0x38 | op->operands[0].regs[0];
3325  } else {
3326  return -1;
3327  }
3328  } else {
3329  return -1;
3330  }
3331  break;
3332  default:
3333  return -1;
3334  }
3335  return l;
3336 }

References OT_DWORD, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opfisttp()

static int opfisttp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3338 of file asm_x86_nz.c.

3338  {
3339  int l = 0;
3340  switch (op->operands_count) {
3341  case 1:
3342  if (op->operands[0].type & OT_MEMORY) {
3343  if (op->operands[0].type & OT_WORD) {
3344  data[l++] = 0xdf;
3345  data[l++] = 0x08 | op->operands[0].regs[0];
3346  } else if (op->operands[0].type & OT_DWORD) {
3347  data[l++] = 0xdb;
3348  data[l++] = 0x08 | op->operands[0].regs[0];
3349  } else if (op->operands[0].type & OT_QWORD) {
3350  data[l++] = 0xdd;
3351  data[l++] = 0x08 | op->operands[0].regs[0];
3352  } else {
3353  return -1;
3354  }
3355  } else {
3356  return -1;
3357  }
3358  break;
3359  default:
3360  return -1;
3361  }
3362  return l;
3363 }

References OT_DWORD, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opfisub()

static int opfisub ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3708 of file asm_x86_nz.c.

3708  {
3709  int l = 0;
3710  switch (op->operands_count) {
3711  case 1:
3712  if (op->operands[0].type & OT_MEMORY) {
3713  if (op->operands[0].type & OT_DWORD) {
3714  data[l++] = 0xda;
3715  data[l++] = 0x20 | op->operands[0].regs[0];
3716  } else if (op->operands[0].type & OT_WORD) {
3717  data[l++] = 0xde;
3718  data[l++] = 0x20 | op->operands[0].regs[0];
3719  } else {
3720  return -1;
3721  }
3722  } else {
3723  return -1;
3724  }
3725  break;
3726  default:
3727  return -1;
3728  }
3729  return l;
3730 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfisubr()

static int opfisubr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3791 of file asm_x86_nz.c.

3791  {
3792  int l = 0;
3793  switch (op->operands_count) {
3794  case 1:
3795  if (op->operands[0].type & OT_MEMORY) {
3796  if (op->operands[0].type & OT_DWORD) {
3797  data[l++] = 0xda;
3798  data[l++] = 0x28 | op->operands[0].regs[0];
3799  } else if (op->operands[0].type & OT_WORD) {
3800  data[l++] = 0xde;
3801  data[l++] = 0x28 | op->operands[0].regs[0];
3802  } else {
3803  return -1;
3804  }
3805  } else {
3806  return -1;
3807  }
3808  break;
3809  default:
3810  return -1;
3811  }
3812  return l;
3813 }

References OT_DWORD, OT_MEMORY, and OT_WORD.

◆ opfldcw()

static int opfldcw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3180 of file asm_x86_nz.c.

3180  {
3181  int l = 0;
3182  switch (op->operands_count) {
3183  case 1:
3184  if (op->operands[0].type & OT_MEMORY &&
3185  op->operands[0].type & OT_WORD) {
3186  data[l++] = 0xd9;
3187  data[l++] = 0x28 | op->operands[0].regs[0];
3188  } else {
3189  return -1;
3190  }
3191  break;
3192  default:
3193  return -1;
3194  }
3195  return l;
3196 }

References OT_MEMORY, and OT_WORD.

◆ opfldenv()

static int opfldenv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3198 of file asm_x86_nz.c.

3198  {
3199  int l = 0;
3200  switch (op->operands_count) {
3201  case 1:
3202  if (op->operands[0].type & OT_MEMORY) {
3203  data[l++] = 0xd9;
3204  data[l++] = 0x20 | op->operands[0].regs[0];
3205  } else {
3206  return -1;
3207  }
3208  break;
3209  default:
3210  return -1;
3211  }
3212  return l;
3213 }

References OT_MEMORY.

◆ opfmul()

static int opfmul ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3566 of file asm_x86_nz.c.

3566  {
3567  int l = 0;
3568  switch (op->operands_count) {
3569  case 1:
3570  if (op->operands[0].type & OT_MEMORY) {
3571  if (op->operands[0].type & OT_DWORD) {
3572  data[l++] = 0xd8;
3573  data[l++] = 0x08 | op->operands[0].regs[0];
3574  } else if (op->operands[0].type & OT_QWORD) {
3575  data[l++] = 0xdc;
3576  data[l++] = 0x08 | op->operands[0].regs[0];
3577  } else {
3578  return -1;
3579  }
3580  } else {
3581  return -1;
3582  }
3583  break;
3584  case 2:
3585  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
3586  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
3587  data[l++] = 0xd8;
3588  data[l++] = 0xc8 | op->operands[1].reg;
3589  } else if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3590  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3591  data[l++] = 0xdc;
3592  data[l++] = 0xc8 | op->operands[0].reg;
3593  } else {
3594  return -1;
3595  }
3596  break;
3597  default:
3598  return -1;
3599  }
3600  return l;
3601 }

References OT_DWORD, OT_FPUREG, OT_MEMORY, OT_QWORD, and OT_REGALL.

◆ opfmulp()

static int opfmulp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3603 of file asm_x86_nz.c.

3603  {
3604  int l = 0;
3605  switch (op->operands_count) {
3606  case 0:
3607  data[l++] = 0xde;
3608  data[l++] = 0xc9;
3609  break;
3610  case 2:
3611  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3612  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3613  data[l++] = 0xde;
3614  data[l++] = 0xc8 | op->operands[0].reg;
3615  } else {
3616  return -1;
3617  }
3618  break;
3619  default:
3620  return -1;
3621  }
3622  return l;
3623 }

References OT_FPUREG, and OT_REGALL.

◆ opfnsave()

static int opfnsave ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3900 of file asm_x86_nz.c.

3900  {
3901  int l = 0;
3902  switch (op->operands_count) {
3903  case 1:
3904  if (op->operands[0].type & OT_MEMORY &&
3905  op->operands[0].type & OT_DWORD) {
3906  data[l++] = 0xdd;
3907  data[l++] = 0x30 | op->operands[0].regs[0];
3908  } else {
3909  return -1;
3910  }
3911  break;
3912  default:
3913  return -1;
3914  }
3915  return l;
3916 }

References OT_DWORD, and OT_MEMORY.

◆ opfnstcw()

static int opfnstcw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3815 of file asm_x86_nz.c.

3815  {
3816  int l = 0;
3817  switch (op->operands_count) {
3818  case 1:
3819  if (op->operands[0].type & OT_MEMORY &&
3820  op->operands[0].type & OT_WORD) {
3821  data[l++] = 0xd9;
3822  data[l++] = 0x38 | op->operands[0].regs[0];
3823  } else {
3824  return -1;
3825  }
3826  break;
3827  default:
3828  return -1;
3829  }
3830  return l;
3831 }

References OT_MEMORY, and OT_WORD.

◆ opfnstenv()

static int opfnstenv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3383 of file asm_x86_nz.c.

3383  {
3384  int l = 0;
3385  switch (op->operands_count) {
3386  case 1:
3387  if (op->operands[0].type & OT_MEMORY) {
3388  data[l++] = 0xd9;
3389  data[l++] = 0x30 | op->operands[0].regs[0];
3390  } else {
3391  return -1;
3392  }
3393  break;
3394  default:
3395  return -1;
3396  }
3397  return l;
3398 }

References OT_MEMORY.

◆ opfnstsw()

static int opfnstsw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3852 of file asm_x86_nz.c.

3852  {
3853  int l = 0;
3854  switch (op->operands_count) {
3855  case 1:
3856  if (op->operands[0].type & OT_MEMORY &&
3857  op->operands[0].type & OT_WORD) {
3858  data[l++] = 0xdd;
3859  data[l++] = 0x38 | op->operands[0].regs[0];
3860  } else if (op->operands[0].type & OT_GPREG &&
3861  op->operands[0].type & OT_WORD &&
3862  op->operands[0].reg == X86R_AX) {
3863  data[l++] = 0xdf;
3864  data[l++] = 0xe0;
3865  } else {
3866  return -1;
3867  }
3868  break;
3869  default:
3870  return -1;
3871  }
3872  return l;
3873 }

References OT_GPREG, OT_MEMORY, OT_WORD, and X86R_AX.

◆ opfrstor()

static int opfrstor ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2942 of file asm_x86_nz.c.

2942  {
2943  int l = 0;
2944  switch (op->operands_count) {
2945  case 1:
2946  if (op->operands[0].type & OT_MEMORY) {
2947  data[l++] = 0xdd;
2948  data[l++] = 0x20 | op->operands[0].regs[0];
2949  } else {
2950  return -1;
2951  }
2952  break;
2953  default:
2954  return -1;
2955  }
2956  return l;
2957 }

References OT_MEMORY.

◆ opfsave()

static int opfsave ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3918 of file asm_x86_nz.c.

3918  {
3919  int l = 0;
3920  switch (op->operands_count) {
3921  case 1:
3922  if (op->operands[0].type & OT_MEMORY &&
3923  op->operands[0].type & OT_DWORD) {
3924  data[l++] = 0x9b;
3925  data[l++] = 0xdd;
3926  data[l++] = 0x30 | op->operands[0].regs[0];
3927  } else {
3928  return -1;
3929  }
3930  break;
3931  default:
3932  return -1;
3933  }
3934  return l;
3935 }

References OT_DWORD, and OT_MEMORY.

◆ opfstcw()

static int opfstcw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3833 of file asm_x86_nz.c.

3833  {
3834  int l = 0;
3835  switch (op->operands_count) {
3836  case 1:
3837  if (op->operands[0].type & OT_MEMORY &&
3838  op->operands[0].type & OT_WORD) {
3839  data[l++] = 0x9b;
3840  data[l++] = 0xd9;
3841  data[l++] = 0x38 | op->operands[0].regs[0];
3842  } else {
3843  return -1;
3844  }
3845  break;
3846  default:
3847  return -1;
3848  }
3849  return l;
3850 }

References OT_MEMORY, and OT_WORD.

◆ opfstenv()

static int opfstenv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3365 of file asm_x86_nz.c.

3365  {
3366  int l = 0;
3367  switch (op->operands_count) {
3368  case 1:
3369  if (op->operands[0].type & OT_MEMORY) {
3370  data[l++] = 0x9b;
3371  data[l++] = 0xd9;
3372  data[l++] = 0x30 | op->operands[0].regs[0];
3373  } else {
3374  return -1;
3375  }
3376  break;
3377  default:
3378  return -1;
3379  }
3380  return l;
3381 }

References OT_MEMORY.

◆ opfstsw()

static int opfstsw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3875 of file asm_x86_nz.c.

3875  {
3876  int l = 0;
3877  switch (op->operands_count) {
3878  case 1:
3879  if (op->operands[0].type & OT_MEMORY &&
3880  op->operands[0].type & OT_WORD) {
3881  data[l++] = 0x9b;
3882  data[l++] = 0xdd;
3883  data[l++] = 0x38 | op->operands[0].regs[0];
3884  } else if (op->operands[0].type & OT_GPREG &&
3885  op->operands[0].type & OT_WORD &&
3886  op->operands[0].reg == X86R_AX) {
3887  data[l++] = 0x9b;
3888  data[l++] = 0xdf;
3889  data[l++] = 0xe0;
3890  } else {
3891  return -1;
3892  }
3893  break;
3894  default:
3895  return -1;
3896  }
3897  return l;
3898 }

References OT_GPREG, OT_MEMORY, OT_WORD, and X86R_AX.

◆ opfsub()

static int opfsub ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3649 of file asm_x86_nz.c.

3649  {
3650  int l = 0;
3651  switch (op->operands_count) {
3652  case 1:
3653  if (op->operands[0].type & OT_MEMORY) {
3654  if (op->operands[0].type & OT_DWORD) {
3655  data[l++] = 0xd8;
3656  data[l++] = 0x20 | op->operands[0].regs[0];
3657  } else if (op->operands[0].type & OT_QWORD) {
3658  data[l++] = 0xdc;
3659  data[l++] = 0x20 | op->operands[0].regs[0];
3660  } else {
3661  return -1;
3662  }
3663  } else {
3664  return -1;
3665  }
3666  break;
3667  case 2:
3668  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
3669  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
3670  data[l++] = 0xd8;
3671  data[l++] = 0xe0 | op->operands[1].reg;
3672  } else if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3673  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3674  data[l++] = 0xdc;
3675  data[l++] = 0xe8 | op->operands[0].reg;
3676  } else {
3677  return -1;
3678  }
3679  break;
3680  default:
3681  return -1;
3682  }
3683  return l;
3684 }

References OT_DWORD, OT_FPUREG, OT_MEMORY, OT_QWORD, and OT_REGALL.

◆ opfsubp()

static int opfsubp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3686 of file asm_x86_nz.c.

3686  {
3687  int l = 0;
3688  switch (op->operands_count) {
3689  case 0:
3690  data[l++] = 0xde;
3691  data[l++] = 0xe9;
3692  break;
3693  case 2:
3694  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3695  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3696  data[l++] = 0xde;
3697  data[l++] = 0xe8 | op->operands[0].reg;
3698  } else {
3699  return -1;
3700  }
3701  break;
3702  default:
3703  return -1;
3704  }
3705  return l;
3706 }

References OT_FPUREG, and OT_REGALL.

◆ opfsubr()

static int opfsubr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3732 of file asm_x86_nz.c.

3732  {
3733  int l = 0;
3734  switch (op->operands_count) {
3735  case 1:
3736  if (op->operands[0].type & OT_MEMORY) {
3737  if (op->operands[0].type & OT_DWORD) {
3738  data[l++] = 0xd8;
3739  data[l++] = 0x28 | op->operands[0].regs[0];
3740  } else if (op->operands[0].type & OT_QWORD) {
3741  data[l++] = 0xdc;
3742  data[l++] = 0x28 | op->operands[0].regs[0];
3743  } else {
3744  return -1;
3745  }
3746  } else {
3747  return -1;
3748  }
3749  break;
3750  case 2:
3751  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL && op->operands[0].reg == 0 &&
3752  op->operands[1].type & OT_FPUREG & ~OT_REGALL) {
3753  data[l++] = 0xd8;
3754  data[l++] = 0xe8 | op->operands[1].reg;
3755  } else if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3756  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3757  data[l++] = 0xdc;
3758  data[l++] = 0xe0 | op->operands[0].reg;
3759  } else {
3760  return -1;
3761  }
3762  break;
3763  default:
3764  return -1;
3765  }
3766  return l;
3767 }

References OT_DWORD, OT_FPUREG, OT_MEMORY, OT_QWORD, and OT_REGALL.

◆ opfsubrp()

static int opfsubrp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3769 of file asm_x86_nz.c.

3769  {
3770  int l = 0;
3771  switch (op->operands_count) {
3772  case 0:
3773  data[l++] = 0xde;
3774  data[l++] = 0xe1;
3775  break;
3776  case 2:
3777  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL &&
3778  op->operands[1].type & OT_FPUREG & ~OT_REGALL && op->operands[1].reg == 0) {
3779  data[l++] = 0xde;
3780  data[l++] = 0xe0 | op->operands[0].reg;
3781  } else {
3782  return -1;
3783  }
3784  break;
3785  default:
3786  return -1;
3787  }
3788  return l;
3789 }

References OT_FPUREG, and OT_REGALL.

◆ opfucom()

static int opfucom ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2980 of file asm_x86_nz.c.

2980  {
2981  int l = 0;
2982  switch (op->operands_count) {
2983  case 1:
2984  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL) {
2985  data[l++] = 0xdd;
2986  data[l++] = 0xe0 | op->operands[0].reg;
2987  } else {
2988  return -1;
2989  }
2990  break;
2991  case 0:
2992  data[l++] = 0xdd;
2993  data[l++] = 0xe1;
2994  break;
2995  default:
2996  return -1;
2997  }
2998  return l;
2999 }

References OT_FPUREG, and OT_REGALL.

◆ opfucomp()

static int opfucomp ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3001 of file asm_x86_nz.c.

3001  {
3002  int l = 0;
3003  switch (op->operands_count) {
3004  case 1:
3005  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL) {
3006  data[l++] = 0xdd;
3007  data[l++] = 0xe8 | op->operands[0].reg;
3008  } else {
3009  return -1;
3010  }
3011  break;
3012  case 0:
3013  data[l++] = 0xdd;
3014  data[l++] = 0xe9;
3015  break;
3016  default:
3017  return -1;
3018  }
3019  return l;
3020 }

References OT_FPUREG, and OT_REGALL.

◆ opfxch()

static int opfxch ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2959 of file asm_x86_nz.c.

2959  {
2960  int l = 0;
2961  switch (op->operands_count) {
2962  case 0:
2963  data[l++] = 0xd9;
2964  data[l++] = 0xc9;
2965  break;
2966  case 1:
2967  if (op->operands[0].type & OT_FPUREG & ~OT_REGALL) {
2968  data[l++] = 0xd9;
2969  data[l++] = 0xc8 | op->operands[0].reg;
2970  } else {
2971  return -1;
2972  }
2973  break;
2974  default:
2975  return -1;
2976  }
2977  return l;
2978 }

References OT_FPUREG, and OT_REGALL.

◆ opfxrstor()

static int opfxrstor ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3251 of file asm_x86_nz.c.

3251  {
3252  int l = 0;
3253  switch (op->operands_count) {
3254  case 1:
3255  if (op->operands[0].type & OT_MEMORY) {
3256  data[l++] = 0x0f;
3257  data[l++] = 0xae;
3258  data[l++] = 0x08 | op->operands[0].regs[0];
3259  } else {
3260  return -1;
3261  }
3262  break;
3263  default:
3264  return -1;
3265  }
3266  return l;
3267 }

References OT_MEMORY.

◆ opfxsave()

static int opfxsave ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3269 of file asm_x86_nz.c.

3269  {
3270  int l = 0;
3271  switch (op->operands_count) {
3272  case 1:
3273  if (op->operands[0].type & OT_MEMORY) {
3274  data[l++] = 0x0f;
3275  data[l++] = 0xae;
3276  data[l++] = 0x00 | op->operands[0].regs[0];
3277  } else {
3278  return -1;
3279  }
3280  break;
3281  default:
3282  return -1;
3283  }
3284  return l;
3285 }

References OT_MEMORY.

◆ opidiv()

static int opidiv ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1202 of file asm_x86_nz.c.

1202  {
1204  int l = 0;
1205 
1206  if (op->operands[0].type & OT_QWORD) {
1207  data[l++] = 0x48;
1208  }
1209  switch (op->operands_count) {
1210  case 1:
1211  if (op->operands[0].type & OT_WORD) {
1212  data[l++] = 0x66;
1213  }
1214  if (op->operands[0].type & OT_BYTE) {
1215  data[l++] = 0xf6;
1216  } else {
1217  data[l++] = 0xf7;
1218  }
1219  if (op->operands[0].type & OT_MEMORY) {
1220  data[l++] = 0x38 | op->operands[0].regs[0];
1221  } else {
1222  data[l++] = 0xf8 | op->operands[0].reg;
1223  }
1224  break;
1225  default:
1226  return -1;
1227  }
1228  return l;
1229 }

References is_valid_registers, OT_BYTE, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opimul()

static int opimul ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1260 of file asm_x86_nz.c.

1260  {
1262  int l = 0;
1263  int offset = 0;
1264  st64 immediate = 0;
1265 
1266  if (op->operands[0].type & OT_QWORD) {
1267  data[l++] = 0x48;
1268  }
1269  switch (op->operands_count) {
1270  case 1:
1271  if (op->operands[0].type & OT_WORD) {
1272  data[l++] = 0x66;
1273  }
1274  if (op->operands[0].type & OT_BYTE) {
1275  data[l++] = 0xf6;
1276  } else {
1277  data[l++] = 0xf7;
1278  }
1279  if (op->operands[0].type & OT_MEMORY) {
1280  data[l++] = 0x28 | op->operands[0].regs[0];
1281  } else {
1282  data[l++] = 0xe8 | op->operands[0].reg;
1283  }
1284  break;
1285  case 2:
1286  if (op->operands[0].type & OT_GPREG) {
1287  if (op->operands[1].type & OT_CONSTANT) {
1288  if (op->operands[1].immediate == -1) {
1289  RZ_LOG_ERROR("assembler: x86.nz: %s: immediate operand exceeds max value (imm == -1)\n", op->mnemonic);
1290  return -1;
1291  }
1292  immediate = op->operands[1].immediate * op->operands[1].sign;
1293  if (op->operands[0].type & OT_GPREG) {
1294  if (immediate >= 128) {
1295  data[l++] = 0x69;
1296  } else {
1297  data[l++] = 0x6b;
1298  }
1299  data[l++] = 0xc0 | op->operands[0].reg << 3 | op->operands[0].reg;
1300  data[l++] = immediate;
1301  if (immediate >= 128) {
1302  data[l++] = immediate >> 8;
1303  data[l++] = immediate >> 16;
1304  data[l++] = immediate >> 24;
1305  }
1306  if (a->bits == 64 && immediate > UT32_MAX) {
1307  data[l++] = immediate >> 32;
1308  data[l++] = immediate >> 40;
1309  data[l++] = immediate >> 48;
1310  data[l++] = immediate >> 56;
1311  }
1312  }
1313  } else if (op->operands[1].type & OT_MEMORY) {
1314  data[l++] = 0x0f;
1315  data[l++] = 0xaf;
1316  if (op->operands[1].regs[0] != X86R_UNDEFINED) {
1317  offset = op->operands[1].offset * op->operands[1].offset_sign;
1318  if (offset != 0) {
1319  if (offset >= 128 || offset <= -128) {
1320  data[l] = 0x80;
1321  } else {
1322  data[l] = 0x40;
1323  }
1324  data[l++] |= op->operands[0].reg << 3 | op->operands[1].regs[0];
1325  data[l++] = offset;
1326  if (offset >= 128 || offset <= -128) {
1327  data[l++] = offset >> 8;
1328  data[l++] = offset >> 16;
1329  data[l++] = offset >> 24;
1330  }
1331  } else {
1332  if (op->operands[1].regs[1] != X86R_UNDEFINED) {
1333  data[l++] = 0x04 | op->operands[0].reg << 3;
1334  data[l++] = op->operands[1].regs[1] << 3 | op->operands[1].regs[0];
1335  } else {
1336  data[l++] = op->operands[0].reg << 3 | op->operands[1].regs[0];
1337  }
1338  }
1339  } else {
1340  immediate = op->operands[1].immediate * op->operands[1].sign;
1341  data[l++] = op->operands[0].reg << 3 | 0x5;
1342  data[l++] = immediate;
1343  data[l++] = immediate >> 8;
1344  data[l++] = immediate >> 16;
1345  data[l++] = immediate >> 24;
1346  }
1347  } else if (op->operands[1].type & OT_GPREG) {
1348  data[l++] = 0x0f;
1349  data[l++] = 0xaf;
1350  data[l++] = 0xc0 | op->operands[0].reg << 3 | op->operands[1].reg;
1351  }
1352  }
1353  break;
1354  case 3:
1355  if (op->operands[0].type & OT_GPREG &&
1356  (op->operands[1].type & OT_GPREG || op->operands[1].type & OT_MEMORY) &&
1357  op->operands[2].type & OT_CONSTANT) {
1358  data[l++] = 0x6b;
1359  if (op->operands[1].type & OT_MEMORY) {
1360  if (op->operands[1].regs[1] != X86R_UNDEFINED) {
1361  data[l++] = 0x04 | op->operands[0].reg << 3;
1362  data[l++] = op->operands[1].regs[0] | op->operands[1].regs[1] << 3;
1363  } else {
1364  offset = op->operands[1].offset * op->operands[1].offset_sign;
1365  if (offset != 0) {
1366  if (offset >= 128 || offset <= -128) {
1367  data[l] = 0x80;
1368  } else {
1369  data[l] = 0x40;
1370  }
1371  data[l++] |= op->operands[0].reg << 3;
1372  data[l++] = offset;
1373  if (offset >= 128 || offset <= -128) {
1374  data[l++] = offset >> 8;
1375  data[l++] = offset >> 16;
1376  data[l++] = offset >> 24;
1377  }
1378  } else {
1379  data[l++] = 0x00 | op->operands[0].reg << 3 | op->operands[1].regs[0];
1380  }
1381  }
1382  } else {
1383  data[l++] = 0xc0 | op->operands[0].reg << 3 | op->operands[1].reg;
1384  }
1385  immediate = op->operands[2].immediate * op->operands[2].sign;
1386  data[l++] = immediate;
1387  if (immediate >= 128 || immediate <= -128) {
1388  data[l++] = immediate >> 8;
1389  data[l++] = immediate >> 16;
1390  data[l++] = immediate >> 24;
1391  }
1392  }
1393  break;
1394  default:
1395  return -1;
1396  }
1397  return l;
1398 }
#define st64
Definition: rz_types_base.h:10
#define UT32_MAX
Definition: rz_types_base.h:99

References a, is_valid_registers, OT_BYTE, OT_CONSTANT, OT_GPREG, OT_MEMORY, OT_QWORD, OT_WORD, RZ_LOG_ERROR, st64, UT32_MAX, and X86R_UNDEFINED.

◆ opin()

static int opin ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1400 of file asm_x86_nz.c.

1400  {
1402  int l = 0;
1403  st32 immediate = 0;
1404  if (op->operands[1].reg == X86R_DX) {
1405  if (op->operands[0].reg == X86R_AL &&
1406  op->operands[0].type & OT_BYTE) {
1407  data[l++] = 0xec;
1408  return l;
1409  }
1410  if (op->operands[0].reg == X86R_AX &&
1411  op->operands[0].type & OT_WORD) {
1412  data[l++] = 0x66;
1413  data[l++] = 0xed;
1414  return l;
1415  }
1416  if (op->operands[0].reg == X86R_EAX &&
1417  op->operands[0].type & OT_DWORD) {
1418  data[l++] = 0xed;
1419  return l;
1420  }
1421  } else if (op->operands[1].type & OT_CONSTANT) {
1422  immediate = op->operands[1].immediate * op->operands[1].sign;
1423  if (immediate > 255 || immediate < -128) {
1424  return -1;
1425  }
1426  if (op->operands[0].reg == X86R_AL &&
1427  op->operands[0].type & OT_BYTE) {
1428  data[l++] = 0xe4;
1429  } else if (op->operands[0].reg == X86R_AX &&
1430  op->operands[0].type & OT_BYTE) {
1431  data[l++] = 0x66;
1432  data[l++] = 0xe5;
1433  } else if (op->operands[0].reg == X86R_EAX &&
1434  op->operands[0].type & OT_DWORD) {
1435  data[l++] = 0xe5;
1436  }
1437  data[l++] = immediate;
1438  }
1439  return l;
1440 }
#define st32
Definition: rz_types_base.h:12

References is_valid_registers, OT_BYTE, OT_CONSTANT, OT_DWORD, OT_WORD, st32, X86R_AL, X86R_AX, X86R_DX, and X86R_EAX.

◆ opinc()

static int opinc ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1472 of file asm_x86_nz.c.

1472  {
1473  if (op->operands[1].type) {
1474  RZ_LOG_ERROR("assembler: x86.nz: %s: invalid operands\n", op->mnemonic);
1475  return -1;
1476  }
1478  int l = 0;
1479  int size = op->operands[0].type & ALL_SIZE;
1480  if (op->operands[0].explicit_size) {
1481  size = op->operands[0].dest_size;
1482  }
1483 
1484  if (size & OT_WORD) {
1485  data[l++] = 0x66;
1486  }
1487 
1488  // rex prefix
1489  int rex = 1 << 6;
1490  bool use_rex = false;
1491  if (size & OT_QWORD) { // W field
1492  use_rex = true;
1493  rex |= 1 << 3;
1494  }
1495  if (op->operands[0].extended) { // B field
1496  use_rex = true;
1497  rex |= 1;
1498  }
1499 
1500  // opcode selection
1501  int opcode;
1502  if (size & OT_BYTE) {
1503  opcode = 0xfe;
1504  } else {
1505  opcode = 0xff;
1506  }
1507 
1508  if (!(op->operands[0].type & OT_MEMORY)) {
1509  if (use_rex) {
1510  data[l++] = rex;
1511  }
1512  if (a->bits > 32 || size & OT_BYTE) {
1513  data[l++] = opcode;
1514  }
1515  if (a->bits == 32 && size & (OT_DWORD | OT_WORD)) {
1516  data[l++] = 0x40 | op->operands[0].reg;
1517  } else {
1518  data[l++] = 0xc0 | op->operands[0].reg;
1519  }
1520  return l;
1521  }
1522 
1523  // modrm and SIB selection
1524  bool rip_rel = op->operands[0].regs[0] == X86R_RIP;
1525  int offset = op->operands[0].offset * op->operands[0].offset_sign;
1526  int modrm = 0;
1527  int mod;
1528  int reg = 0;
1529  int rm;
1530  bool use_sib = false;
1531  int sib = 0;
1532  // mod
1533  if (offset == 0) {
1534  mod = 0;
1535  } else if (offset < 128 && offset > -129) {
1536  mod = 1;
1537  } else {
1538  mod = 2;
1539  }
1540 
1541  if (op->operands[0].regs[0] & OT_WORD) {
1542  if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == X86R_SI) {
1543  rm = B0000;
1544  } else if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == X86R_DI) {
1545  rm = B0001;
1546  } else if (op->operands[0].regs[0] == X86R_BP && op->operands[0].regs[1] == X86R_SI) {
1547  rm = B0010;
1548  } else if (op->operands[0].regs[0] == X86R_BP && op->operands[0].regs[1] == X86R_DI) {
1549  rm = B0011;
1550  } else if (op->operands[0].regs[0] == X86R_SI && op->operands[0].regs[1] == -1) {
1551  rm = B0100;
1552  } else if (op->operands[0].regs[0] == X86R_DI && op->operands[0].regs[1] == -1) {
1553  rm = B0101;
1554  } else if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == -1) {
1555  rm = B0111;
1556  } else {
1557  // TODO allow for displacement only when parser is reworked
1558  return -1;
1559  }
1560  modrm = (mod << 6) | (reg << 3) | rm;
1561  } else {
1562  // rm
1563  if (op->operands[0].extended) {
1564  rm = op->operands[0].reg;
1565  } else {
1566  rm = op->operands[0].regs[0];
1567  }
1568  //[epb] alone is illegal, so we need to fake a [ebp+0]
1569  if (rm == 5 && mod == 0) {
1570  mod = 1;
1571  }
1572 
1573  // sib
1574  int index = op->operands[0].regs[1];
1575  int scale = getsib(op->operands[0].scale[1]);
1576  if (index != -1) {
1577  use_sib = true;
1578  sib = (scale << 6) | (index << 3) | rm;
1579  } else if (rm == 4) {
1580  use_sib = true;
1581  sib = 0x24;
1582  }
1583  if (use_sib) {
1584  rm = B0100;
1585  }
1586  if (rip_rel) {
1587  modrm = (B0000 << 6) | (reg << 3) | B0101;
1588  sib = (scale << 6) | (B0100 << 3) | B0101;
1589  } else {
1590  modrm = (mod << 6) | (reg << 3) | rm;
1591  }
1592  }
1593 
1594  if (use_rex) {
1595  data[l++] = rex;
1596  }
1597  data[l++] = opcode;
1598  data[l++] = modrm;
1599  if (use_sib) {
1600  data[l++] = sib;
1601  }
1602  // offset
1603  if (mod == 1) {
1604  data[l++] = offset;
1605  } else if (op->operands[0].regs[0] & OT_WORD && mod == 2) {
1606  data[l++] = offset;
1607  data[l++] = offset >> 8;
1608  } else if (mod == 2 || rip_rel) {
1609  data[l++] = offset;
1610  data[l++] = offset >> 8;
1611  data[l++] = offset >> 16;
1612  data[l++] = offset >> 24;
1613  }
1614 
1615  return l;
1616 }

References a, ALL_SIZE, B0000, B0001, B0010, B0011, B0100, B0101, B0111, getsib(), is_valid_registers, mod(), OT_BYTE, OT_DWORD, OT_MEMORY, OT_QWORD, OT_WORD, reg, RZ_LOG_ERROR, X86R_BP, X86R_BX, X86R_DI, X86R_RIP, and X86R_SI.

◆ opint()

static int opint ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1618 of file asm_x86_nz.c.

1618  {
1619  int l = 0;
1620  if (op->operands[0].type & OT_CONSTANT) {
1621  st32 immediate = op->operands[0].immediate * op->operands[0].sign;
1622  if (immediate <= 255 && immediate >= -128) {
1623  data[l++] = 0xcd;
1624  data[l++] = immediate;
1625  }
1626  }
1627  return l;
1628 }

References OT_CONSTANT, and st32.

◆ opjc()

static int opjc ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1630 of file asm_x86_nz.c.

1630  {
1632  int l = 0;
1633  bool is_short = op->is_short;
1634  // st64 bigimm = op->operands[0].immediate * op->operands[0].sign;
1635  st64 immediate = op->operands[0].immediate * op->operands[0].sign;
1636  if (is_short && (immediate > ST8_MAX || immediate < ST8_MIN)) {
1637  return l;
1638  }
1639  immediate -= a->pc;
1640  if (immediate > ST32_MAX || immediate < -ST32_MAX) {
1641  return -1;
1642  }
1643  if (!strcmp(op->mnemonic, "jmp")) {
1644  if (op->operands[0].type & OT_GPREG) {
1645  data[l++] = 0xff;
1646  if (op->operands[0].type & OT_MEMORY) {
1647  if (op->operands[0].offset) {
1648  int offset = op->operands[0].offset * op->operands[0].offset_sign;
1649  if (offset >= 128 || offset <= -129) {
1650  data[l] = 0xa0;
1651  } else {
1652  data[l] = 0x60;
1653  }
1654  data[l++] |= op->operands[0].regs[0];
1655  if (op->operands[0].regs[0] == X86R_ESP) {
1656  data[l++] = 0x24;
1657  }
1658  data[l++] = offset;
1659  if (op->operands[0].offset >= 0x80) {
1660  data[l++] = offset >> 8;
1661  data[l++] = offset >> 16;
1662  data[l++] = offset >> 24;
1663  }
1664  } else {
1665  data[l++] = 0x20 | op->operands[0].regs[0];
1666  }
1667  } else {
1668  data[l++] = 0xe0 | op->operands[0].reg;
1669  }
1670  } else {
1671  if (-0x80 <= (immediate - 2) && (immediate - 2) <= 0x7f) {
1672  /* relative byte address */
1673  data[l++] = 0xeb;
1674  data[l++] = immediate - 2;
1675  } else {
1676  /* relative address */
1677  immediate -= 5;
1678  data[l++] = 0xe9;
1679  data[l++] = immediate;
1680  data[l++] = immediate >> 8;
1681  data[l++] = immediate >> 16;
1682  data[l++] = immediate >> 24;
1683  }
1684  }
1685  return l;
1686  }
1687  if (immediate <= 0x81 && immediate > -0x7f) {
1688  is_short = true;
1689  }
1690  if (a->bits == 16 && (immediate > 0x81 || immediate < -0x7e)) {
1691  data[l++] = 0x66;
1692  is_short = false;
1693  immediate--;
1694  }
1695 
1696  if (!is_short) {
1697  data[l++] = 0x0f;
1698  }
1699  if (!strcmp(op->mnemonic, "ja") ||
1700  !strcmp(op->mnemonic, "jnbe")) {
1701  data[l++] = 0x87;
1702  } else if (!strcmp(op->mnemonic, "jae") ||
1703  !strcmp(op->mnemonic, "jnb") ||
1704  !strcmp(op->mnemonic, "jnc")) {
1705  data[l++] = 0x83;
1706  } else if (!strcmp(op->mnemonic, "jz") ||
1707  !strcmp(op->mnemonic, "je")) {
1708  data[l++] = 0x84;
1709  } else if (!strcmp(op->mnemonic, "jb") ||
1710  !strcmp(op->mnemonic, "jnae") ||
1711  !strcmp(op->mnemonic, "jc")) {
1712  data[l++] = 0x82;
1713  } else if (!strcmp(op->mnemonic, "jbe") ||
1714  !strcmp(op->mnemonic, "jna")) {
1715  data[l++] = 0x86;
1716  } else if (!strcmp(op->mnemonic, "jg") ||
1717  !strcmp(op->mnemonic, "jnle")) {
1718  data[l++] = 0x8f;
1719  } else if (!strcmp(op->mnemonic, "jge") ||
1720  !strcmp(op->mnemonic, "jnl")) {
1721  data[l++] = 0x8d;
1722  } else if (!strcmp(op->mnemonic, "jl") ||
1723  !strcmp(op->mnemonic, "jnge")) {
1724  data[l++] = 0x8c;
1725  } else if (!strcmp(op->mnemonic, "jle") ||
1726  !strcmp(op->mnemonic, "jng")) {
1727  data[l++] = 0x8e;
1728  } else if (!strcmp(op->mnemonic, "jne") ||
1729  !strcmp(op->mnemonic, "jnz")) {
1730  data[l++] = 0x85;
1731  } else if (!strcmp(op->mnemonic, "jno")) {
1732  data[l++] = 0x81;
1733  } else if (!strcmp(op->mnemonic, "jnp") ||
1734  !strcmp(op->mnemonic, "jpo")) {
1735  data[l++] = 0x8b;
1736  } else if (!strcmp(op->mnemonic, "jns")) {
1737  data[l++] = 0x89;
1738  } else if (!strcmp(op->mnemonic, "jo")) {
1739  data[l++] = 0x80;
1740  } else if (!strcmp(op->mnemonic, "jp") ||
1741  !strcmp(op->mnemonic, "jpe")) {
1742  data[l++] = 0x8a;
1743  } else if (!strcmp(op->mnemonic, "js") ||
1744  !strcmp(op->mnemonic, "jz")) {
1745  data[l++] = 0x88;
1746  }
1747  if (is_short) {
1748  data[l - 1] -= 0x10;
1749  }
1750 
1751  immediate -= is_short ? 2 : 6;
1752  data[l++] = immediate;
1753  if (!is_short) {
1754  data[l++] = immediate >> 8;
1755  data[l++] = immediate >> 16;
1756  data[l++] = immediate >> 24;
1757  }
1758  return l;
1759 }
#define ST8_MIN
#define ST32_MAX
Definition: rz_types_base.h:97

References a, is_valid_registers, OT_GPREG, OT_MEMORY, ST32_MAX, st64, ST8_MAX, ST8_MIN, and X86R_ESP.

◆ oplea()

static int oplea ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1761 of file asm_x86_nz.c.

1761  {
1762  int l = 0;
1763  int mod = 0;
1764  st32 offset = 0;
1765  int reg = 0;
1766  int rm = 0;
1767  if (op->operands[0].type & OT_REGALL &&
1768  op->operands[1].type & (OT_MEMORY | OT_CONSTANT)) {
1769  if (a->bits == 64) {
1770  data[l++] = 0x48;
1771  }
1772  data[l++] = 0x8d;
1773  if (op->operands[1].regs[0] == X86R_UNDEFINED) {
1774  // RIP-relative LEA
1775  ut64 offset = op->operands[1].offset - a->pc;
1776  if (data[0] == 0x48) {
1777  offset -= 7;
1778  }
1779  ut32 high = 0xff00 & offset;
1780  data[l++] = op->operands[0].reg << 3 | 5;
1781  data[l++] = offset;
1782  data[l++] = high >> 8;
1783  data[l++] = offset >> 16;
1784  data[l++] = offset >> 24;
1785  return l;
1786  } else {
1787  reg = op->operands[0].reg;
1788  rm = op->operands[1].regs[0];
1789 
1790  offset = op->operands[1].offset * op->operands[1].offset_sign;
1791  if (op->operands[1].regs[0] == X86R_RIP) {
1792  // RIP-relative LEA (not caught above, so "offset" is already relative)
1793  data[l++] = reg << 3 | 5;
1794  data[l++] = offset;
1795  data[l++] = offset >> 8;
1796  data[l++] = offset >> 16;
1797  data[l++] = offset >> 24;
1798  return l;
1799  }
1800  if (offset != 0 || op->operands[1].regs[0] == X86R_EBP) {
1801  mod = 1;
1802  if (offset >= 128 || offset < -128) {
1803  mod = 2;
1804  }
1805  data[l++] = mod << 6 | reg << 3 | rm;
1806  if (op->operands[1].regs[0] == X86R_ESP) {
1807  data[l++] = 0x24;
1808  }
1809  data[l++] = offset;
1810  if (mod == 2) {
1811  data[l++] = offset >> 8;
1812  data[l++] = offset >> 16;
1813  data[l++] = offset >> 24;
1814  }
1815  } else {
1816  data[l++] = op->operands[0].reg << 3 | op->operands[1].regs[0];
1817  if (op->operands[1].regs[0] == X86R_ESP) {
1818  data[l++] = 0x24;
1819  }
1820  }
1821  }
1822  }
1823  return l;
1824 }
uint32_t ut32

References a, mod(), OT_CONSTANT, OT_MEMORY, OT_REGALL, reg, st32, ut64(), X86R_EBP, X86R_ESP, X86R_RIP, and X86R_UNDEFINED.

◆ oples()

static int oples ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1826 of file asm_x86_nz.c.

1826  {
1827  int l = 0;
1828  int offset = 0;
1829  int mod = 0;
1830 
1831  if (op->operands[1].type & OT_MEMORY) {
1832  data[l++] = 0xc4;
1833  if (op->operands[1].type & OT_GPREG) {
1834  offset = op->operands[1].offset * op->operands[1].offset_sign;
1835  if (offset) {
1836  mod = 1;
1837  if (offset > 128 || offset < -128) {
1838  mod = 2;
1839  }
1840  }
1841  data[l++] = mod << 6 | op->operands[0].reg << 3 | op->operands[1].regs[0];
1842  if (mod) {
1843  data[l++] = offset;
1844  if (mod > 1) {
1845  data[l++] = offset >> 8;
1846  data[l++] = offset >> 16;
1847  data[l++] = offset >> 24;
1848  }
1849  }
1850  } else {
1851  offset = op->operands[1].offset * op->operands[1].offset_sign;
1852  data[l++] = 0x05;
1853  data[l++] = offset;
1854  data[l++] = offset >> 8;
1855  data[l++] = offset >> 16;
1856  data[l++] = offset >> 24;
1857  }
1858  }
1859  return l;
1860 }

References mod(), OT_GPREG, and OT_MEMORY.

◆ oplgdt()

static int oplgdt ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3981 of file asm_x86_nz.c.

3981  {
3982  int l = 0;
3983  switch (op->operands_count) {
3984  case 1:
3985  if (op->operands[0].type & OT_MEMORY) {
3986  data[l++] = 0x0f;
3987  data[l++] = 0x01;
3988  data[l++] = 0x10 | op->operands[0].regs[0];
3989  } else {
3990  return -1;
3991  }
3992  break;
3993  default:
3994  return -1;
3995  }
3996  return l;
3997 }

References OT_MEMORY.

◆ oplidt()

static int oplidt ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3999 of file asm_x86_nz.c.

3999  {
4000  int l = 0;
4001  switch (op->operands_count) {
4002  case 1:
4003  if (op->operands[0].type & OT_MEMORY) {
4004  data[l++] = 0x0f;
4005  data[l++] = 0x01;
4006  data[l++] = 0x18 | op->operands[0].regs[0];
4007  } else {
4008  return -1;
4009  }
4010  break;
4011  default:
4012  return -1;
4013  }
4014  return l;
4015 }

References OT_MEMORY.

◆ oplldt()

static int oplldt ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3937 of file asm_x86_nz.c.

3937  {
3938  int l = 0;
3939  switch (op->operands_count) {
3940  case 1:
3941  if (op->operands[0].type & OT_WORD) {
3942  data[l++] = 0x0f;
3943  data[l++] = 0x00;
3944  if (op->operands[0].type & OT_MEMORY) {
3945  data[l++] = 0x10 | op->operands[0].regs[0];
3946  } else {
3947  data[l++] = 0xd0 | op->operands[0].reg;
3948  }
3949  } else {
3950  return -1;
3951  }
3952  break;
3953  default:
3954  return -1;
3955  }
3956  return l;
3957 }

References OT_MEMORY, and OT_WORD.

◆ oplmsw()

static int oplmsw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 3959 of file asm_x86_nz.c.

3959  {
3960  int l = 0;
3961  switch (op->operands_count) {
3962  case 1:
3963  if (op->operands[0].type & OT_WORD) {
3964  data[l++] = 0x0f;
3965  data[l++] = 0x01;
3966  if (op->operands[0].type & OT_MEMORY) {
3967  data[l++] = 0x30 | op->operands[0].regs[0];
3968  } else {
3969  data[l++] = 0xf0 | op->operands[0].reg;
3970  }
3971  } else {
3972  return -1;
3973  }
3974  break;
3975  default:
3976  return -1;
3977  }
3978  return l;
3979 }

References OT_MEMORY, and OT_WORD.

◆ oploop()

static int oploop ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2585 of file asm_x86_nz.c.

2585  {
2587  int l = 0;
2588  data[l++] = 0xe2;
2589  st8 delta = op->operands[0].immediate - a->pc - 2;
2590  data[l++] = (ut8)delta;
2591  return l;
2592 }
#define ut8
Definition: dcpu16.h:8
#define st8
Definition: rz_types_base.h:16
static st64 delta
Definition: vmenus.c:2425

References a, delta, is_valid_registers, st8, and ut8.

◆ opmov()

static int opmov ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1862 of file asm_x86_nz.c.

1862  {
1863  int l = 0;
1864  st64 offset = 0;
1865  int mod = 0;
1866  int base = 0;
1867  int rex = 0;
1868  ut64 immediate = 0;
1869  if (op->operands[1].type & OT_CONSTANT) {
1870  if (!op->operands[1].is_good_flag) {
1871  return -1;
1872  }
1873  if (op->operands[1].immediate == -1 && a->num && a->num->nc.errors > 0) {
1874  return -1;
1875  }
1876  immediate = op->operands[1].immediate * op->operands[1].sign;
1877  if (op->operands[0].type & OT_GPREG && !(op->operands[0].type & OT_MEMORY)) {
1878  if ((op->operands[0].type & OT_DWORD) &&
1879  immediate > UT32_MAX && immediate < 0xffffffff80000000ULL /* -0x80000000 */) {
1880  return -1;
1881  }
1882  bool imm32in64 = false;
1883  if (a->bits == 64 && (op->operands[0].type & OT_QWORD)) {
1884  if (op->operands[0].extended) {
1885  data[l++] = 0x49;
1886  } else {
1887  data[l++] = 0x48;
1888  }
1889  } else if (op->operands[0].extended) {
1890  data[l++] = 0x41;
1891  }
1892  if (op->operands[0].type & OT_WORD) {
1893  if (a->bits > 16) {
1894  data[l++] = 0x66;
1895  }
1896  }
1897  if (op->operands[0].type & OT_BYTE) {
1898  data[l++] = 0xb0 | op->operands[0].reg;
1899  data[l++] = immediate;
1900  } else {
1901  if (a->bits == 64 && (op->operands[0].type & OT_QWORD) &&
1902  (immediate <= ST32_MAX || immediate >= 0xffffffff80000000ULL /* -0x80000000 */)) {
1903  data[l++] = 0xc7;
1904  data[l++] = 0xc0 | op->operands[0].reg;
1905  imm32in64 = true;
1906  } else {
1907  data[l++] = 0xb8 | op->operands[0].reg;
1908  }
1909  data[l++] = immediate;
1910  data[l++] = immediate >> 8;
1911  if (!(op->operands[0].type & OT_WORD)) {
1912  data[l++] = immediate >> 16;
1913  data[l++] = immediate >> 24;
1914  }
1915  if (a->bits == 64 &&
1916  (((op->operands[0].type & OT_QWORD) && !imm32in64) ||
1917  (immediate > UT32_MAX && immediate < 0xffffffff80000000ULL /* -0x80000000 */))) {
1918  data[l++] = immediate >> 32;
1919  data[l++] = immediate >> 40;
1920  data[l++] = immediate >> 48;
1921  data[l++] = immediate >> 56;
1922  }
1923  }
1924  } else if (op->operands[0].type & OT_MEMORY) {
1925  if (!op->operands[0].explicit_size) {
1926  if (op->operands[0].type & OT_GPREG) {
1927  ((Opcode *)op)->operands[0].dest_size = op->operands[0].reg_size;
1928  } else {
1929  return -1;
1930  }
1931  }
1932 
1933  int dest_bits = 8 * ((op->operands[0].dest_size & ALL_SIZE) >> OPSIZE_SHIFT);
1934  int reg_bits = 8 * ((op->operands[0].reg_size & ALL_SIZE) >> OPSIZE_SHIFT);
1935  int offset = op->operands[0].offset * op->operands[0].offset_sign;
1936 
1937  // addr_size_override prefix
1938  bool use_aso = false;
1939  if (reg_bits < a->bits) {
1940  use_aso = true;
1941  }
1942 
1943  // op_size_override prefix
1944  bool use_oso = false;
1945  if (dest_bits == 16) {
1946  use_oso = true;
1947  }
1948 
1949  bool rip_rel = op->operands[0].regs[0] == X86R_RIP;
1950 
1951  // rex prefix
1952  int rex = 1 << 6;
1953  bool use_rex = false;
1954  if (dest_bits == 64) { // W field
1955  use_rex = true;
1956  rex |= 1 << 3;
1957  }
1958  if (op->operands[0].extended) { // B field
1959  use_rex = true;
1960  rex |= 1;
1961  }
1962 
1963  // opcode selection
1964  int opcode;
1965  if (dest_bits == 8) {
1966  opcode = 0xc6;
1967  } else {
1968  opcode = 0xc7;
1969  }
1970 
1971  // modrm and SIB selection
1972  int modrm = 0;
1973  int mod;
1974  int reg = 0;
1975  int rm;
1976  bool use_sib = false;
1977  int sib;
1978  // mod
1979  if (offset == 0) {
1980  mod = 0;
1981  } else if (offset < 128 && offset > -129) {
1982  mod = 1;
1983  } else {
1984  mod = 2;
1985  }
1986 
1987  if (reg_bits == 16) {
1988  if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == X86R_SI) {
1989  rm = B0000;
1990  } else if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == X86R_DI) {
1991  rm = B0001;
1992  } else if (op->operands[0].regs[0] == X86R_BP && op->operands[0].regs[1] == X86R_SI) {
1993  rm = B0010;
1994  } else if (op->operands[0].regs[0] == X86R_BP && op->operands[0].regs[1] == X86R_DI) {
1995  rm = B0011;
1996  } else if (op->operands[0].regs[0] == X86R_SI && op->operands[0].regs[1] == -1) {
1997  rm = B0100;
1998  } else if (op->operands[0].regs[0] == X86R_DI && op->operands[0].regs[1] == -1) {
1999  rm = B0101;
2000  } else if (op->operands[0].regs[0] == X86R_BX && op->operands[0].regs[1] == -1) {
2001  rm = B0111;
2002  } else {
2003  // TODO allow for displacement only when parser is reworked
2004  return -1;
2005  }
2006  modrm = (mod << 6) | (reg << 3) | rm;
2007  } else {
2008  // rm
2009  if (op->operands[0].extended) {
2010  rm = op->operands[0].reg;
2011  } else {
2012  rm = op->operands[0].regs[0];
2013  }
2014  //[epb] alone is illegal, so we need to fake a [ebp+0]
2015  if (rm == 5 && mod == 0) {
2016  mod = 1;
2017  }
2018 
2019  // sib
2020  int index = op->operands[0].regs[1];
2021  int scale = getsib(op->operands[0].scale[1]);
2022  if (index != -1) {
2023  use_sib = true;
2024  sib = (scale << 6) | (index << 3) | rm;
2025  } else if (rm == 4) {
2026  use_sib = true;
2027  sib = 0x24;
2028  }
2029  if (use_sib) {
2030  rm = B0100;
2031  }
2032  if (rip_rel) {
2033  modrm = (B0000 << 6) | (reg << 3) | B0101;
2034  sib = (scale << 6) | (B0100 << 3) | B0101;
2035  } else {
2036  modrm = (mod << 6) | (reg << 3) | rm;
2037  }
2038  }
2039 
2040  // build the final result
2041  if (use_aso) {
2042  data[l++] = 0x67;
2043  }
2044  if (use_oso) {
2045  data[l++] = 0x66;
2046  }
2047  if (use_rex) {
2048  data[l++] = rex;
2049  }
2050  data[l++] = opcode;
2051  data[l++] = modrm;
2052  if (use_sib) {
2053  data[l++] = sib;
2054  }
2055  // offset
2056  if (mod == 1) {
2057  data[l++] = offset;
2058  } else if (reg_bits == 16 && mod == 2) {
2059  data[l++] = offset;
2060  data[l++] = offset >> 8;
2061  } else if (mod == 2 || rip_rel) {
2062  data[l++] = offset;
2063  data[l++] = offset >> 8;
2064  data[l++] = offset >> 16;
2065  data[l++] = offset >> 24;
2066  }
2067  // immediate
2068  int byte;
2069  for (byte = 0; byte < dest_bits && byte < 32; byte += 8) {
2070  data[l++] = (immediate >> byte);
2071  }
2072  }
2073  } else if (op->operands[1].type & OT_REGALL &&
2074  !(op->operands[1].type & OT_MEMORY)) {
2075  if (op->operands[0].type & OT_CONSTANT) {
2076  return -1;
2077  }
2078  if (op->operands[0].type & OT_REGTYPE & OT_SEGMENTREG &&
2079  op->operands[1].type & OT_REGTYPE & OT_SEGMENTREG) {
2080  return -1;
2081  }
2082  if (is_debug_or_control(op->operands[0]) &&
2083  !(op->operands[1].type & OT_REGTYPE & OT_GPREG)) {
2084  return -1;
2085  }
2086  if (is_debug_or_control(op->operands[1]) &&
2087  !(op->operands[0].type & OT_REGTYPE & OT_GPREG)) {
2088  return -1;
2089  }
2090  // Check reg sizes match
2091  if (op->operands[0].type & OT_REGTYPE && op->operands[1].type & OT_REGTYPE) {
2092  if (!((op->operands[0].type & ALL_SIZE) &
2093  (op->operands[1].type & ALL_SIZE))) {
2094  return -1;
2095  }
2096  }
2097 
2098  if (a->bits == 64) {
2099  if (op->operands[0].extended) {
2100  rex = 1;
2101  }
2102  if (op->operands[1].extended) {
2103  rex += 4;
2104  }
2105  if (op->operands[1].type & OT_QWORD) {
2106  if (!(op->operands[0].type & OT_QWORD)) {
2107  data[l++] = 0x67;
2108  data[l++] = 0x48;
2109  }
2110  }
2111  if (op->operands[1].type & OT_QWORD &&
2112  op->operands[0].type & OT_QWORD) {
2113  data[l++] = 0x48 | rex;
2114  }
2115  if (op->operands[1].type & OT_DWORD &&
2116  op->operands[0].type & OT_DWORD) {
2117  data[l++] = 0x40 | rex;
2118  }
2119  } else if (op->operands[0].extended && op->operands[1].extended) {
2120  data[l++] = 0x45;
2121  }
2122  offset = op->operands[0].offset * op->operands[0].offset_sign;
2123  if (op->operands[1].type & OT_REGTYPE & OT_SEGMENTREG) {
2124  data[l++] = 0x8c;
2125  } else if (is_debug_or_control(op->operands[0])) {
2126  data[l++] = 0x0f;
2127  if (op->operands[0].type & OT_REGTYPE & OT_DEBUGREG) {
2128  data[l++] = 0x23;
2129  } else {
2130  data[l++] = 0x22;
2131  }
2132  } else if (is_debug_or_control(op->operands[1])) {
2133  data[l++] = 0x0f;
2134  if (op->operands[1].type & OT_REGTYPE & OT_DEBUGREG) {
2135  data[l++] = 0x21;
2136  } else {
2137  data[l++] = 0x20;
2138  }
2139  } else {
2140  if (op->operands[0].type & OT_WORD) {
2141  data[l++] = 0x66;
2142  }
2143  data[l++] = (op->operands[0].type & OT_BYTE) ? 0x88 : 0x89;
2144  }
2145 
2146  if (op->operands[0].scale[0] > 1) {
2147  data[l++] = op->operands[1].reg << 3 | 4;
2148  data[l++] = getsib(op->operands[0].scale[0]) << 6 |
2149  op->operands[0].regs[0] << 3 | 5;
2150 
2151  data[l++] = offset;
2152  data[l++] = offset >> 8;
2153  data[l++] = offset >> 16;
2154  data[l++] = offset >> 24;
2155 
2156  return l;
2157  }
2158 
2159  if (!(op->operands[0].type & OT_MEMORY)) {
2160  if (op->operands[0].reg == X86R_UNDEFINED ||
2161  op->operands[1].reg == X86R_UNDEFINED) {
2162  return -1;
2163  }
2164  mod = 0x3;
2165  data[l++] = (is_debug_or_control(op->operands[0]))
2166  ? mod << 6 | op->operands[0].reg << 3 | op->operands[1].reg
2167  : mod << 6 | op->operands[1].reg << 3 | op->operands[0].reg;
2168  } else if (op->operands[0].regs[0] == X86R_UNDEFINED) {
2169  data[l++] = op->operands[1].reg << 3 | 0x5;
2170  data[l++] = offset;
2171  data[l++] = offset >> 8;
2172  data[l++] = offset >> 16;
2173  data[l++] = offset >> 24;
2174  } else {
2175  if (op->operands[0].type & OT_MEMORY) {
2176  if (op->operands[0].regs[1] != X86R_UNDEFINED) {
2177  data[l++] = op->operands[1].reg << 3 | 0x4;
2178  data[l++] = op->operands[0].regs[1] << 3 | op->operands[0].regs[0];
2179  return l;
2180  }
2181  if (offset) {
2182  mod = (offset > 128 || offset < -129) ? 0x2 : 0x1;
2183  }
2184  if (op->operands[0].regs[0] == X86R_EBP) {
2185  mod = 0x2;
2186  }
2187  data[l++] = mod << 6 | op->operands[1].reg << 3 | op->operands[0].regs[0];
2188  if (op->operands[0].regs[0] == X86R_ESP) {
2189  data[l++] = 0x24;
2190  }
2191  if (offset) {
2192  data[l++] = offset;
2193  }
2194  if (mod == 2) {
2195  // warning C4293: '>>': shift count negative or too big, undefined behavior
2196  data[l++] = offset >> 8;
2197  data[l++] = offset >> 16;
2198  data[l++] = offset >> 24;
2199  }
2200  }
2201  }
2202  } else if (op->operands[1].type & OT_MEMORY) {
2203  if (op->operands[0].type & OT_MEMORY) {
2204  return -1;
2205  }
2206  offset = op->operands[1].offset * op->operands[1].offset_sign;
2207  if (op->operands[0].reg == X86R_EAX && op->operands[1].regs[0] == X86R_UNDEFINED) {
2208  if (op->operands[0].type & OT_QWORD) {
2209  data[l++] = 0x48;
2210  } else if (op->operands[0].type & OT_WORD && a->bits != 16) {
2211  data[l++] = 0x66;
2212  }
2213  if (op->operands[0].type & OT_BYTE) {
2214  data[l++] = 0xa0;
2215  } else {
2216  data[l++] = 0xa1;
2217  }
2218  data[l++] = offset;
2219  data[l++] = offset >> 8;
2220  if (a->bits >= 32) {
2221  data[l++] = offset >> 16;
2222  data[l++] = offset >> 24;
2223  if (a->bits == 64) {
2224  data[l++] = offset >> 32;
2225  data[l++] = offset >> 40;
2226  data[l++] = offset >> 48;
2227  data[l++] = offset >> 56;
2228  }
2229  }
2230  return l;
2231  }
2232  if (op->operands[0].type & OT_BYTE && a->bits == 64 && op->operands[1].regs[0]) {
2233  if (op->operands[1].regs[0] >= X86R_R8 &&
2234  op->operands[0].reg < 4) {
2235  data[l++] = 0x41;
2236  data[l++] = 0x8a;
2237  data[l++] = op->operands[0].reg << 3 | (op->operands[1].regs[0] - 8);
2238  return l;
2239  }
2240  return -1;
2241  }
2242 
2243  if (op->operands[1].type & OT_REGTYPE & OT_SEGMENTREG) {
2244  if (op->operands[1].scale[0] == 0) {
2245  return -1;
2246  }
2247  data[l++] = SEG_REG_PREFIXES[op->operands[1].regs[0] % 6];
2248  data[l++] = 0x8b;
2249  data[l++] = (((ut32)op->operands[0].reg) << 3) | 0x5;
2250  data[l++] = offset;
2251  data[l++] = offset >> 8;
2252  data[l++] = offset >> 16;
2253  data[l++] = offset >> 24;
2254  return l;
2255  }
2256 
2257  if (a->bits == 64) {
2258  if (op->operands[0].type & OT_QWORD) {
2259  if (!(op->operands[1].type & OT_QWORD)) {
2260  if (op->operands[1].regs[0] != -1) {
2261  data[l++] = 0x67;
2262  }
2263  data[l++] = 0x48;
2264  }
2265  } else if (op->operands[1].type & OT_DWORD) {
2266  data[l++] = 0x44;
2267  } else if (!(op->operands[1].type & OT_QWORD)) {
2268  data[l++] = 0x67;
2269  }
2270  if (op->operands[1].type & OT_QWORD &&
2271  op->operands[0].type & OT_QWORD) {
2272  data[l++] = 0x48;
2273  }
2274  }
2275 
2276  if (op->operands[0].type & OT_WORD) {
2277  data[l++] = 0x66;
2278  data[l++] = op->operands[1].type & OT_BYTE ? 0x8a : 0x8b;
2279  } else {
2280  data[l++] = (op->operands[1].type & OT_BYTE ||
2281  op->operands[0].type & OT_BYTE)
2282  ? 0x8a
2283  : 0x8b;
2284  }
2285 
2286  if (op->operands[1].regs[0] == X86R_UNDEFINED) {
2287  if (a->bits == 64) {
2288  data[l++] = op->operands[0].reg << 3 | 0x4;
2289  data[l++] = 0x25;
2290  } else {
2291  data[l++] = op->operands[0].reg << 3 | 0x5;
2292  }
2293  data[l++] = offset;
2294  data[l++] = offset >> 8;
2295  data[l++] = offset >> 16;
2296  data[l++] = offset >> 24;
2297  } else {
2298  if (op->operands[1].scale[0] > 1) {
2299  data[l++] = op->operands[0].reg << 3 | 4;
2300 
2301  if (op->operands[1].scale[0] >= 2) {
2302  base = 5;
2303  }
2304  if (base) {
2305  data[l++] = getsib(op->operands[1].scale[0]) << 6 | op->operands[1].regs[0] << 3 | base;
2306  } else {
2307  data[l++] = getsib(op->operands[1].scale[0]) << 3 | op->operands[1].regs[0];
2308  }
2309  if (offset || base) {
2310  data[l++] = offset;
2311  data[l++] = offset >> 8;
2312  data[l++] = offset >> 16;
2313  data[l++] = offset >> 24;
2314  }
2315  return l;
2316  }
2317  if (op->operands[1].regs[1] != X86R_UNDEFINED) {
2318  data[l++] = op->operands[0].reg << 3 | 0x4;
2319  data[l++] = op->operands[1].regs[1] << 3 | op->operands[1].regs[0];
2320  return l;
2321  }
2322 
2323  if (offset || op->operands[1].regs[0] == X86R_EBP) {
2324  mod = 0x2;
2325  if (op->operands[1].offset > 127) {
2326  mod = 0x4;
2327  }
2328  }
2329  if (a->bits == 64 && offset && op->operands[0].type & OT_QWORD) {
2330  if (op->operands[1].regs[0] == X86R_RIP) {
2331  data[l++] = 0x5;
2332  } else {
2333  const ut8 pfx = (op->operands[1].offset > 127) ? 0x80 : 0x40;
2334  data[l++] = pfx | op->operands[0].reg << 3 | op->operands[1].regs[0];
2335  }
2336  if (op->operands[1].offset > 127) {
2337  mod = 0x1;
2338  }
2339  } else {
2340  if (op->operands[1].regs[0] == X86R_EIP && (op->operands[0].type & OT_DWORD)) {
2341  data[l++] = 0x0d;
2342  } else if (op->operands[1].regs[0] == X86R_RIP && (op->operands[0].type & OT_QWORD)) {
2343  data[l++] = 0x05;
2344  } else {
2345  data[l++] = mod << 5 | op->operands[0].reg << 3 | op->operands[1].regs[0];
2346  }
2347  }
2348  if (op->operands[1].regs[0] == X86R_ESP) {
2349  data[l++] = 0x24;
2350  }
2351  if (mod >= 0x2) {
2352  data[l++] = offset;
2353  if (op->operands[1].offset > 128 || op->operands[1].regs[0] == X86R_EIP) {
2354  data[l++] = offset >> 8;
2355  data[l++] = offset >> 16;
2356  data[l++] = offset >> 24;
2357  }
2358  } else if (a->bits == 64 && (offset || op->operands[1].regs[0] == X86R_RIP)) {
2359  data[l++] = offset;
2360  if (op->operands[1].offset > 127 || op->operands[1].regs[0] == X86R_RIP) {
2361  data[l++] = offset >> 8;
2362  data[l++] = offset >> 16;
2363  data[l++] = offset >> 24;
2364  }
2365  }
2366  }
2367  }
2368  return l;
2369 }
static ut32 reg_bits(arm_reg reg)
Definition: arm_il32.c:82
const ut8 SEG_REG_PREFIXES[]
Definition: asm_x86_nz.c:83
#define OT_SEGMENTREG
Definition: asm_x86_nz.c:34
#define OPSIZE_SHIFT
Definition: asm_x86_nz.c:19
int bits(struct state *s, int need)
Definition: blast.c:72

References a, ALL_SIZE, B0000, B0001, B0010, B0011, B0100, B0101, B0111, bits(), getsib(), is_debug_or_control(), mod(), OPSIZE_SHIFT, OT_BYTE, OT_CONSTANT, OT_DEBUGREG, OT_DWORD, OT_GPREG, OT_MEMORY, OT_QWORD, OT_REGALL, OT_REGTYPE, OT_SEGMENTREG, OT_WORD, reg, reg_bits(), SEG_REG_PREFIXES, st64, UT32_MAX, ut64(), X86R_BP, X86R_BX, X86R_DI, X86R_EAX, X86R_EBP, X86R_EIP, X86R_ESP, X86R_R8, X86R_RIP, X86R_SI, and X86R_UNDEFINED.

◆ opmovabs()

static int opmovabs ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2372 of file asm_x86_nz.c.

2372  {
2373  if (!(a->bits == 64 && (op->operands[0].type & OT_GPREG) && !(op->operands[0].type & OT_MEMORY) &&
2374  (op->operands[0].type & OT_QWORD) && (op->operands[1].type & OT_CONSTANT))) {
2375  return -1;
2376  }
2377  int l = 0;
2378  int byte_shift;
2379  ut64 immediate;
2380  if (op->operands[0].extended) {
2381  data[l++] = 0x49;
2382  } else {
2383  data[l++] = 0x48;
2384  }
2385  data[l++] = 0xb8 | op->operands[0].reg;
2386  immediate = op->operands[1].immediate * op->operands[1].sign;
2387  for (byte_shift = 0; byte_shift < 8; byte_shift++) {
2388  data[l++] = immediate >> (byte_shift * 8);
2389  }
2390  return l;
2391 }

References a, OT_CONSTANT, OT_GPREG, OT_MEMORY, OT_QWORD, and ut64().

◆ opmovx()

static int opmovx ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 1015 of file asm_x86_nz.c.

1015  {
1017  int l = 0;
1018  int word = 0;
1019  char *movx = op->mnemonic + 3;
1020 
1021  if (!(op->operands[0].type & OT_REGTYPE && op->operands[1].type & OT_MEMORY)) {
1022  return -1;
1023  }
1024  if (op->operands[1].type & OT_WORD) {
1025  word = 1;
1026  }
1027 
1028  data[l++] = 0x0f;
1029  if (!strcmp(movx, "zx")) {
1030  data[l++] = 0xb6 + word;
1031  } else if (!strcmp(movx, "sx")) {
1032  data[l++] = 0xbe + word;
1033  }
1034  data[l++] = op->operands[0].reg << 3 | op->operands[1].regs[0];
1035  if (op->operands[1].regs[0] == X86R_ESP) {
1036  data[l++] = 0x24;
1037  }
1038 
1039  return l;
1040 }

References is_valid_registers, OT_MEMORY, OT_REGTYPE, OT_WORD, and X86R_ESP.

◆ opmul()

static int opmul ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2393 of file asm_x86_nz.c.

2393  {
2395  int l = 0;
2396 
2397  if (op->operands[0].type & OT_QWORD) {
2398  data[l++] = 0x48;
2399  }
2400  switch (op->operands_count) {
2401  case 1:
2402  if (op->operands[0].type & OT_WORD) {
2403  data[l++] = 0x66;
2404  }
2405  if (op->operands[0].type & OT_BYTE) {
2406  data[l++] = 0xf6;
2407  } else {
2408  data[l++] = 0xf7;
2409  }
2410  if (op->operands[0].type & OT_MEMORY) {
2411  data[l++] = 0x20 | op->operands[0].regs[0];
2412  } else {
2413  data[l++] = 0xe0 | op->operands[0].reg;
2414  }
2415  break;
2416  default:
2417  return -1;
2418  }
2419  return l;
2420 }

References is_valid_registers, OT_BYTE, OT_MEMORY, OT_QWORD, and OT_WORD.

◆ opneg()

static int opneg ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 687 of file asm_x86_nz.c.

687  {
689  int l = 0;
690 
691  if (op->operands[0].type & OT_GPREG) {
692  if (op->operands[0].type & OT_WORD) {
693  data[l++] = 0x66;
694  } else if (op->operands[0].type & OT_QWORD) {
695  data[l++] = 0x48;
696  }
697 
698  if (op->operands[0].type & OT_BYTE) {
699  data[l++] = 0xf6;
700  } else {
701  data[l++] = 0xf7;
702  }
703  data[l++] = 0xd8 | op->operands[0].reg;
704  return l;
705  }
706  return -1;
707 }

References is_valid_registers, OT_BYTE, OT_GPREG, OT_QWORD, and OT_WORD.

◆ opnot()

static int opnot ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 719 of file asm_x86_nz.c.

719  {
721  int l = 0;
722 
723  if (op->operands[0].reg == X86R_UNDEFINED) {
724  return -1;
725  }
726 
727  int size = op->operands[0].type & ALL_SIZE;
728  if (op->operands[0].explicit_size) {
729  size = op->operands[0].dest_size;
730  }
731  // rex prefix
732  int rex = 1 << 6;
733  bool use_rex = false;
734  if (size & OT_QWORD) { // W field
735  use_rex = true;
736  rex |= 1 << 3;
737  }
738  if (op->operands[0].extended) { // B field
739  use_rex = true;
740  rex |= 1;
741  }
742 
743  if (use_rex) {
744  data[l++] = rex;
745  }
746  data[l++] = 0xf7;
747  data[l++] = 0xd0 | op->operands[0].reg;
748 
749  return l;
750 }

References ALL_SIZE, is_valid_registers, OT_QWORD, and X86R_UNDEFINED.

◆ opor()

static int opor ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 626 of file asm_x86_nz.c.

626  {
627  if (op->operands[1].type & OT_CONSTANT) {
628  if (op->operands[0].type & OT_GPREG &&
629  op->operands[0].type & OT_WORD) {
630  return process_16bit_group_1(a, data, op, 0x08);
631  }
632  if (!is_al_reg(&op->operands[0])) {
633  return process_group_1(a, data, op);
634  }
635  }
636  return process_1byte_op(a, data, op, 0x08);
637 }

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ opout()

static int opout ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2545 of file asm_x86_nz.c.

2545  {
2547  int l = 0;
2548  st32 immediate = 0;
2549  if (op->operands[0].reg == X86R_DX) {
2550  if (op->operands[1].reg == X86R_AL && op->operands[1].type & OT_BYTE) {
2551  data[l++] = 0xee;
2552  return l;
2553  }
2554  if (op->operands[1].reg == X86R_AX && op->operands[1].type & OT_WORD) {
2555  data[l++] = 0x66;
2556  data[l++] = 0xef;
2557  return l;
2558  }
2559  if (op->operands[1].reg == X86R_EAX && op->operands[1].type & OT_DWORD) {
2560  data[l++] = 0xef;
2561  return l;
2562  }
2563  } else if (op->operands[0].type & OT_CONSTANT) {
2564  immediate = op->operands[0].immediate * op->operands[0].sign;
2565  if (immediate > 255 || immediate < -128) {
2566  return -1;
2567  }
2568  if (op->operands[1].reg == X86R_AL && op->operands[1].type & OT_BYTE) {
2569  data[l++] = 0xe6;
2570  } else if (op->operands[1].reg == X86R_AX && op->operands[1].type & OT_WORD) {
2571  data[l++] = 0x66;
2572  data[l++] = 0xe7;
2573  } else if (op->operands[1].reg == X86R_EAX && op->operands[1].type & OT_DWORD) {
2574  data[l++] = 0xe7;
2575  } else {
2576  return -1;
2577  }
2578  data[l++] = immediate;
2579  } else {
2580  return -1;
2581  }
2582  return l;
2583 }

References is_valid_registers, OT_BYTE, OT_CONSTANT, OT_DWORD, OT_WORD, st32, X86R_AL, X86R_AX, X86R_DX, and X86R_EAX.

◆ oppop()

static int oppop ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2422 of file asm_x86_nz.c.

2422  {
2424  int l = 0;
2425  int offset = 0;
2426  int mod = 0;
2427  if (op->operands[0].type & OT_GPREG) {
2428  if (op->operands[0].type & OT_MEMORY) {
2429  return -1;
2430  }
2431  if (op->operands[0].type & OT_REGTYPE & OT_SEGMENTREG) {
2432  ut8 base;
2433  if (op->operands[0].reg & X86R_FS) {
2434  data[l++] = 0x0f;
2435  base = 0x81;
2436  } else {
2437  base = 0x7;
2438  }
2439  data[l++] = base + (8 * op->operands[0].reg);
2440  } else {
2441  if (op->operands[0].extended && a->bits == 64) {
2442  data[l++] = 0x41;
2443  }
2444  ut8 base = 0x58;
2445  data[l++] = base + op->operands[0].reg;
2446  }
2447  } else if (op->operands[0].type & OT_MEMORY) {
2448  data[l++] = 0x8f;
2449  offset = op->operands[0].offset * op->operands[0].offset_sign;
2450  if (offset != 0 || op->operands[0].regs[0] == X86R_EBP) {
2451  mod = 1;
2452  if (offset >= 128 || offset < -128) {
2453  mod = 2;
2454  }
2455  data[l++] = mod << 6 | op->operands[0].regs[0];
2456  if (op->operands[0].regs[0] == X86R_ESP) {
2457  data[l++] = 0x24;
2458  }
2459  data[l++] = offset;
2460  if (mod == 2) {
2461  data[l++] = offset >> 8;
2462  data[l++] = offset >> 16;
2463  data[l++] = offset >> 24;
2464  }
2465  } else {
2466  data[l++] = op->operands[0].regs[0];
2467  if (op->operands[0].regs[0] == X86R_ESP) {
2468  data[l++] = 0x24;
2469  }
2470  }
2471  }
2472  return l;
2473 }

References a, is_valid_registers, mod(), OT_GPREG, OT_MEMORY, OT_REGTYPE, OT_SEGMENTREG, X86R_EBP, X86R_ESP, and X86R_FS.

◆ oppush()

static int oppush ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2475 of file asm_x86_nz.c.

2475  {
2477  int l = 0;
2478  int mod = 0;
2479  st32 immediate = 0;
2480  ;
2481  st32 offset = 0;
2482  if (op->operands[0].type & OT_GPREG &&
2483  !(op->operands[0].type & OT_MEMORY)) {
2484  if (op->operands[0].type & OT_REGTYPE & OT_SEGMENTREG) {
2485  ut8 base;
2486  if (op->operands[0].reg & X86R_FS) {
2487  data[l++] = 0x0f;
2488  base = 0x80;
2489  } else {
2490  base = 0x6;
2491  }
2492  data[l++] = base + (8 * op->operands[0].reg);
2493  } else {
2494  if (op->operands[0].extended && a->bits == 64) {
2495  data[l++] = 0x41;
2496  }
2497  ut8 base = 0x50;
2498  if (op->operands[0].reg == X86R_RIP) {
2499  RZ_LOG_ERROR("assembler: x86.nz: %s: invalid register (rip)\n", op->mnemonic);
2500  return -1;
2501  }
2502  data[l++] = base + op->operands[0].reg;
2503  }
2504  } else if (op->operands[0].type & OT_MEMORY) {
2505  data[l++] = 0xff;
2506  offset = op->operands[0].offset * op->operands[0].offset_sign;
2507  if (offset != 0 || op->operands[0].regs[0] == X86R_EBP) {
2508  mod = 1;
2509  if (offset >= 128 || offset < -128) {
2510  mod = 2;
2511  }
2512  data[l++] = mod << 6 | 6 << 3 | op->operands[0].regs[0];
2513  if (op->operands[0].regs[0] == X86R_ESP) {
2514  data[l++] = 0x24;
2515  }
2516  data[l++] = offset;
2517  if (mod == 2) {
2518  data[l++] = offset >> 8;
2519  data[l++] = offset >> 16;
2520  data[l++] = offset >> 24;
2521  }
2522  } else {
2523  mod = 3;
2524  data[l++] = mod << 4 | op->operands[0].regs[0];
2525  if (op->operands[0].regs[0] == X86R_ESP) {
2526  data[l++] = 0x24;
2527  }
2528  }
2529  } else {
2530  immediate = op->operands[0].immediate * op->operands[0].sign;
2531  if (immediate >= 128 || immediate < -128) {
2532  data[l++] = 0x68;
2533  data[l++] = immediate;
2534  data[l++] = immediate >> 8;
2535  data[l++] = immediate >> 16;
2536  data[l++] = immediate >> 24;
2537  } else {
2538  data[l++] = 0x6a;
2539  data[l++] = immediate;
2540  }
2541  }
2542  return l;
2543 }

References a, is_valid_registers, mod(), OT_GPREG, OT_MEMORY, OT_REGTYPE, OT_SEGMENTREG, RZ_LOG_ERROR, st32, X86R_EBP, X86R_ESP, X86R_FS, and X86R_RIP.

◆ oprep()

static int oprep ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 5149 of file asm_x86_nz.c.

5149  {
5150  int l = 0;
5151  LookupTable *lt_ptr;
5152  int retval;
5153  if (!strcmp(op->mnemonic, "rep") ||
5154  !strcmp(op->mnemonic, "repe") ||
5155  !strcmp(op->mnemonic, "repz")) {
5156  data[l++] = 0xf3;
5157  } else if (!strcmp(op->mnemonic, "repne") ||
5158  !strcmp(op->mnemonic, "repnz")) {
5159  data[l++] = 0xf2;
5160  }
5161  Opcode instr = { 0 };
5162  parseOpcode(a, op->operands[0].rep_op, &instr);
5163 
5164  for (lt_ptr = oplookup; strcmp(lt_ptr->mnemonic, "null"); lt_ptr++) {
5165  if (!rz_str_casecmp(instr.mnemonic, lt_ptr->mnemonic)) {
5166  if (lt_ptr->opcode > 0) {
5167  if (lt_ptr->only_x32 && a->bits == 64) {
5168  free(instr.mnemonic);
5169  return -1;
5170  }
5171  ut64 opcode = lt_ptr->opcode;
5172  int i = lt_ptr->size - 1;
5173  for (; i >= 0; i--) {
5174  data[i + l] = opcode & 0xff;
5175  opcode >>= 8;
5176  }
5177  free(instr.mnemonic);
5178  return l + lt_ptr->size;
5179  } else {
5180  if (lt_ptr->opdo) {
5181  data += l;
5182  if (instr.has_bnd) {
5183  data[l] = 0xf2;
5184  data++;
5185  }
5186  retval = lt_ptr->opdo(a, data, &instr);
5187  // if op supports bnd then the first byte will
5188  // be 0xf2.
5189  if (instr.has_bnd) {
5190  retval++;
5191  }
5192  return l + retval;
5193  }
5194  break;
5195  }
5196  }
5197  }
5198  free(instr.mnemonic);
5199  return -1;
5200 }

References a, free(), Opcode_t::has_bnd, i, Opcode_t::mnemonic, lookup_t::mnemonic, lookup_t::only_x32, lookup_t::opcode, lookup_t::opdo, oplookup, parseOpcode(), rz_str_casecmp(), lookup_t::size, and ut64().

◆ opret()

static int opret ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2594 of file asm_x86_nz.c.

2594  {
2595  int l = 0;
2596  int immediate = 0;
2597  if (a->bits == 16) {
2598  data[l++] = 0xc3;
2599  return l;
2600  }
2601  if (op->operands[0].type == OT_UNKNOWN) {
2602  data[l++] = 0xc3;
2603  } else if (op->operands[0].type & (OT_CONSTANT | OT_WORD)) {
2604  data[l++] = 0xc2;
2605  immediate = op->operands[0].immediate * op->operands[0].sign;
2606  data[l++] = immediate;
2607  data[l++] = immediate << 8;
2608  }
2609  return l;
2610 }
#define OT_UNKNOWN
Definition: asm_x86_nz.c:48

References a, OT_CONSTANT, OT_UNKNOWN, and OT_WORD.

◆ opretf()

static int opretf ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2612 of file asm_x86_nz.c.

2612  {
2613  int l = 0;
2614  st32 immediate = 0;
2615  if (op->operands[0].type & OT_CONSTANT) {
2616  immediate = op->operands[0].immediate * op->operands[0].sign;
2617  data[l++] = 0xca;
2618  data[l++] = immediate;
2619  data[l++] = immediate >> 8;
2620  } else if (op->operands[0].type == OT_UNKNOWN) {
2621  data[l++] = 0xcb;
2622  }
2623  return l;
2624 }

References OT_CONSTANT, OT_UNKNOWN, and st32.

◆ opsbb()

static int opsbb ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 752 of file asm_x86_nz.c.

752  {
753  if (op->operands[1].type & OT_CONSTANT) {
754  if (op->operands[0].type & OT_GPREG &&
755  op->operands[0].type & OT_WORD) {
756  return process_16bit_group_1(a, data, op, 0x18);
757  }
758  if (!is_al_reg(&op->operands[0])) {
759  return process_group_1(a, data, op);
760  }
761  }
762  return process_1byte_op(a, data, op, 0x18);
763 }

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ opset()

static int opset ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2642 of file asm_x86_nz.c.

2642  {
2643  if (!(op->operands[0].type & (OT_GPREG | OT_BYTE))) {
2644  return -1;
2645  }
2646  int l = 0;
2647  int mod = 0;
2648  int reg = op->operands[0].regs[0];
2649 
2650  data[l++] = 0x0f;
2651  if (!strcmp(op->mnemonic, "seto")) {
2652  data[l++] = 0x90;
2653  } else if (!strcmp(op->mnemonic, "setno")) {
2654  data[l++] = 0x91;
2655  } else if (!strcmp(op->mnemonic, "setb") ||
2656  !strcmp(op->mnemonic, "setnae") ||
2657  !strcmp(op->mnemonic, "setc")) {
2658  data[l++] = 0x92;
2659  } else if (!strcmp(op->mnemonic, "setnb") ||
2660  !strcmp(op->mnemonic, "setae") ||
2661  !strcmp(op->mnemonic, "setnc")) {
2662  data[l++] = 0x93;
2663  } else if (!strcmp(op->mnemonic, "setz") ||
2664  !strcmp(op->mnemonic, "sete")) {
2665  data[l++] = 0x94;
2666  } else if (!strcmp(op->mnemonic, "setnz") ||
2667  !strcmp(op->mnemonic, "setne")) {
2668  data[l++] = 0x95;
2669  } else if (!strcmp(op->mnemonic, "setbe") ||
2670  !strcmp(op->mnemonic, "setna")) {
2671  data[l++] = 0x96;
2672  } else if (!strcmp(op->mnemonic, "setnbe") ||
2673  !strcmp(op->mnemonic, "seta")) {
2674  data[l++] = 0x97;
2675  } else if (!strcmp(op->mnemonic, "sets")) {
2676  data[l++] = 0x98;
2677  } else if (!strcmp(op->mnemonic, "setns")) {
2678  data[l++] = 0x99;
2679  } else if (!strcmp(op->mnemonic, "setp") ||
2680  !strcmp(op->mnemonic, "setpe")) {
2681  data[l++] = 0x9a;
2682  } else if (!strcmp(op->mnemonic, "setnp") ||
2683  !strcmp(op->mnemonic, "setpo")) {
2684  data[l++] = 0x9b;
2685  } else if (!strcmp(op->mnemonic, "setl") ||
2686  !strcmp(op->mnemonic, "setnge")) {
2687  data[l++] = 0x9c;
2688  } else if (!strcmp(op->mnemonic, "setnl") ||
2689  !strcmp(op->mnemonic, "setge")) {
2690  data[l++] = 0x9d;
2691  } else if (!strcmp(op->mnemonic, "setle") ||
2692  !strcmp(op->mnemonic, "setng")) {
2693  data[l++] = 0x9e;
2694  } else if (!strcmp(op->mnemonic, "setnle") ||
2695  !strcmp(op->mnemonic, "setg")) {
2696  data[l++] = 0x9f;
2697  } else {
2698  return -1;
2699  }
2700  if (!(op->operands[0].type & OT_MEMORY)) {
2701  mod = 3;
2702  reg = op->operands[0].reg;
2703  }
2704  data[l++] = mod << 6 | reg;
2705  return l;
2706 }

References mod(), OT_BYTE, OT_GPREG, OT_MEMORY, and reg.

◆ opsgdt()

static int opsgdt ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4017 of file asm_x86_nz.c.

4017  {
4018  int l = 0;
4019  switch (op->operands_count) {
4020  case 1:
4021  if (op->operands[0].type & OT_MEMORY) {
4022  data[l++] = 0x0f;
4023  data[l++] = 0x01;
4024  data[l++] = 0x00 | op->operands[0].regs[0];
4025  } else {
4026  return -1;
4027  }
4028  break;
4029  default:
4030  return -1;
4031  }
4032  return l;
4033 }

References OT_MEMORY.

◆ opsidt()

static int opsidt ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4078 of file asm_x86_nz.c.

4078  {
4079  int l = 0;
4080  switch (op->operands_count) {
4081  case 1:
4082  if (op->operands[0].type & OT_MEMORY) {
4083  data[l++] = 0x0f;
4084  data[l++] = 0x01;
4085  data[l++] = 0x08 | op->operands[0].regs[0];
4086  } else {
4087  return -1;
4088  }
4089  break;
4090  default:
4091  return -1;
4092  }
4093  return l;
4094 }

References OT_MEMORY.

◆ opsldt()

static int opsldt ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4096 of file asm_x86_nz.c.

4096  {
4097  int l = 0;
4098  switch (op->operands_count) {
4099  case 1:
4100  if (a->bits == 64) {
4101  data[l++] = 0x48;
4102  }
4103  data[l++] = 0x0f;
4104  data[l++] = 0x00;
4105  if (op->operands[0].type & OT_MEMORY) {
4106  data[l++] = 0x00 | op->operands[0].regs[0];
4107  } else {
4108  data[l++] = 0xc0 | op->operands[0].reg;
4109  }
4110  break;
4111  default:
4112  return -1;
4113  }
4114  return l;
4115 }

References a, and OT_MEMORY.

◆ opsmsw()

static int opsmsw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4117 of file asm_x86_nz.c.

4117  {
4118  int l = 0;
4119  switch (op->operands_count) {
4120  case 1:
4121  if (a->bits == 64) {
4122  data[l++] = 0x48;
4123  }
4124  data[l++] = 0x0f;
4125  data[l++] = 0x01;
4126  if (op->operands[0].type & OT_MEMORY) {
4127  data[l++] = 0x20 | op->operands[0].regs[0];
4128  } else {
4129  data[l++] = 0xe0 | op->operands[0].reg;
4130  }
4131  break;
4132  default:
4133  return -1;
4134  }
4135  return l;
4136 }

References a, and OT_MEMORY.

◆ opstmxcsr()

static int opstmxcsr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4035 of file asm_x86_nz.c.

4035  {
4036  int l = 0;
4037  switch (op->operands_count) {
4038  case 1:
4039  if (op->operands[0].type & OT_MEMORY &&
4040  op->operands[0].type & OT_DWORD) {
4041  data[l++] = 0x0f;
4042  data[l++] = 0xae;
4043  data[l++] = 0x18 | op->operands[0].regs[0];
4044  } else {
4045  return -1;
4046  }
4047  break;
4048  default:
4049  return -1;
4050  }
4051  return l;
4052 }

References OT_DWORD, and OT_MEMORY.

◆ opstos()

static int opstos ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2626 of file asm_x86_nz.c.

2626  {
2628  int l = 0;
2629  if (!strcmp(op->mnemonic, "stosw")) {
2630  data[l++] = 0x66;
2631  }
2632  if (!strcmp(op->mnemonic, "stosb")) {
2633  data[l++] = 0xaa;
2634  } else if (!strcmp(op->mnemonic, "stosw")) {
2635  data[l++] = 0xab;
2636  } else if (!strcmp(op->mnemonic, "stosd")) {
2637  data[l++] = 0xab;
2638  }
2639  return l;
2640 }

References is_valid_registers.

◆ opstr()

static int opstr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4054 of file asm_x86_nz.c.

4054  {
4055  int l = 0;
4056  switch (op->operands_count) {
4057  case 1:
4058  if (op->operands[0].type & OT_MEMORY &&
4059  op->operands[0].type & OT_WORD) {
4060  data[l++] = 0x0f;
4061  data[l++] = 0x00;
4062  data[l++] = 0x08 | op->operands[0].regs[0];
4063  } else if (op->operands[0].type & OT_GPREG &&
4064  op->operands[0].type & OT_DWORD) {
4065  data[l++] = 0x0f;
4066  data[l++] = 0x00;
4067  data[l++] = 0xc8 | op->operands[0].reg;
4068  } else {
4069  return -1;
4070  }
4071  break;
4072  default:
4073  return -1;
4074  }
4075  return l;
4076 }

References OT_DWORD, OT_GPREG, OT_MEMORY, and OT_WORD.

Referenced by __disassemble(), asm_pic_disassemble(), disassemble(), do_analysis_search(), ds_atabs_option(), ds_disassemble(), mips_assemble(), print_rop(), rz_core_disasm_pdi_with_buf(), rz_parse_filter_dup(), rz_parse_immtrim(), and skipdata_opstr().

◆ opsub()

static int opsub ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 613 of file asm_x86_nz.c.

613  {
614  if (op->operands[1].type & OT_CONSTANT) {
615  if (op->operands[0].type & OT_GPREG &&
616  op->operands[0].type & OT_WORD) {
617  return process_16bit_group_1(a, data, op, 0x28);
618  }
619  if (!is_al_reg(&op->operands[0])) {
620  return process_group_1(a, data, op);
621  }
622  }
623  return process_1byte_op(a, data, op, 0x28);
624 }

References a, is_al_reg(), OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), and process_group_1().

◆ optest()

static int optest ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2708 of file asm_x86_nz.c.

2708  {
2710  int l = 0;
2711  if (!op->operands[0].type || !op->operands[1].type) {
2712  RZ_LOG_ERROR("assembler: x86.nz: %s: invalid operands\n", op->mnemonic);
2713  return -1;
2714  }
2715  if (a->bits == 64) {
2716  if (op->operands[0].type & OT_MEMORY &&
2717  op->operands[0].reg_size & OT_DWORD) {
2718  data[l++] = 0x67;
2719  }
2720  if (op->operands[0].type & OT_QWORD) {
2721  if (op->operands[0].extended &&
2722  op->operands[1].extended) {
2723  data[l++] = 0x4d;
2724  } else {
2725  data[l++] = 0x48;
2726  }
2727  }
2728  }
2729 
2730  if (op->operands[1].type & OT_CONSTANT) {
2731  if (op->operands[0].type & OT_BYTE) {
2732  data[l++] = 0xf6;
2733  } else {
2734  if (op->operands[0].type & OT_WORD && a->bits != 16) {
2735  data[l++] = 0x66;
2736  }
2737  data[l++] = 0xf7;
2738  }
2739  if (op->operands[0].type & OT_MEMORY) {
2740  data[l++] = 0x00 | op->operands[0].reg;
2741  } else {
2742  data[l++] = 0xc0 | op->operands[0].reg;
2743  }
2744  data[l++] = op->operands[1].immediate >> 0;
2745  if (op->operands[0].type & OT_BYTE) {
2746  return l;
2747  }
2748  data[l++] = op->operands[1].immediate >> 8;
2749  if (op->operands[0].type & OT_WORD) {
2750  return l;
2751  }
2752  data[l++] = op->operands[1].immediate >> 16;
2753  data[l++] = op->operands[1].immediate >> 24;
2754  return l;
2755  }
2756  if (op->operands[0].type & OT_BYTE ||
2757  op->operands[1].type & OT_BYTE) {
2758  data[l++] = 0x84;
2759  } else {
2760  data[l++] = 0x85;
2761  }
2762  if (op->operands[0].type & OT_MEMORY) {
2763  data[l++] = 0x00 | op->operands[1].reg << 3 | op->operands[0].regs[0];
2764  } else {
2765  if (op->operands[1].type & OT_MEMORY) {
2766  data[l++] = 0x00 | op->operands[0].reg << 3 | op->operands[1].regs[0];
2767  } else {
2768  data[l++] = 0xc0 | op->operands[1].reg << 3 | op->operands[0].reg;
2769  }
2770  }
2771  return l;
2772 }

References a, is_valid_registers, OT_BYTE, OT_CONSTANT, OT_DWORD, OT_MEMORY, OT_QWORD, OT_WORD, and RZ_LOG_ERROR.

◆ opverr()

static int opverr ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4138 of file asm_x86_nz.c.

4138  {
4139  int l = 0;
4140  switch (op->operands_count) {
4141  case 1:
4142  if (op->operands[0].type & OT_WORD) {
4143  data[l++] = 0x0f;
4144  data[l++] = 0x00;
4145  if (op->operands[0].type & OT_MEMORY) {
4146  data[l++] = 0x20 | op->operands[0].regs[0];
4147  } else {
4148  data[l++] = 0xe0 | op->operands[0].reg;
4149  }
4150  } else {
4151  return -1;
4152  }
4153  break;
4154  default:
4155  return -1;
4156  }
4157  return l;
4158 }

References OT_MEMORY, and OT_WORD.

◆ opverw()

static int opverw ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4160 of file asm_x86_nz.c.

4160  {
4161  int l = 0;
4162  switch (op->operands_count) {
4163  case 1:
4164  if (op->operands[0].type & OT_WORD) {
4165  data[l++] = 0x0f;
4166  data[l++] = 0x00;
4167  if (op->operands[0].type & OT_MEMORY) {
4168  data[l++] = 0x28 | op->operands[0].regs[0];
4169  } else {
4170  data[l++] = 0xe8 | op->operands[0].reg;
4171  }
4172  } else {
4173  return -1;
4174  }
4175  break;
4176  default:
4177  return -1;
4178  }
4179  return l;
4180 }

References OT_MEMORY, and OT_WORD.

◆ opvmclear()

static int opvmclear ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4182 of file asm_x86_nz.c.

4182  {
4183  int l = 0;
4184  switch (op->operands_count) {
4185  case 1:
4186  if (op->operands[0].type & OT_MEMORY &&
4187  op->operands[0].type & OT_QWORD) {
4188  data[l++] = 0x66;
4189  data[l++] = 0x0f;
4190  data[l++] = 0xc7;
4191  data[l++] = 0x30 | op->operands[0].regs[0];
4192  } else {
4193  return -1;
4194  }
4195  break;
4196  default:
4197  return -1;
4198  }
4199  return l;
4200 }

References OT_MEMORY, and OT_QWORD.

◆ opvmon()

static int opvmon ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4202 of file asm_x86_nz.c.

4202  {
4203  int l = 0;
4204  switch (op->operands_count) {
4205  case 1:
4206  if (op->operands[0].type & OT_MEMORY &&
4207  op->operands[0].type & OT_QWORD) {
4208  data[l++] = 0xf3;
4209  data[l++] = 0x0f;
4210  data[l++] = 0xc7;
4211  data[l++] = 0x30 | op->operands[0].regs[0];
4212  } else {
4213  return -1;
4214  }
4215  break;
4216  default:
4217  return -1;
4218  }
4219  return l;
4220 }

References OT_MEMORY, and OT_QWORD.

◆ opvmptrld()

static int opvmptrld ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4222 of file asm_x86_nz.c.

4222  {
4223  int l = 0;
4224  switch (op->operands_count) {
4225  case 1:
4226  if (op->operands[0].type & OT_MEMORY &&
4227  op->operands[0].type & OT_QWORD) {
4228  data[l++] = 0x0f;
4229  data[l++] = 0xc7;
4230  data[l++] = 0x30 | op->operands[0].regs[0];
4231  } else {
4232  return -1;
4233  }
4234  break;
4235  default:
4236  return -1;
4237  }
4238  return l;
4239 }

References OT_MEMORY, and OT_QWORD.

◆ opvmptrst()

static int opvmptrst ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 4241 of file asm_x86_nz.c.

4241  {
4242  int l = 0;
4243  switch (op->operands_count) {
4244  case 1:
4245  if (op->operands[0].type & OT_MEMORY &&
4246  op->operands[0].type & OT_QWORD) {
4247  data[l++] = 0x0f;
4248  data[l++] = 0xc7;
4249  data[l++] = 0x38 | op->operands[0].regs[0];
4250  } else {
4251  return -1;
4252  }
4253  break;
4254  default:
4255  return -1;
4256  }
4257  return l;
4258 }

References OT_MEMORY, and OT_QWORD.

◆ opxadd()

static int opxadd ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 639 of file asm_x86_nz.c.

639  {
641  int i = 0;
642  if (op->operands_count < 2) {
643  return -1;
644  }
645  if (a->bits == 64) {
646  data[i++] = 0x48;
647  };
648  data[i++] = 0x0f;
649  if (op->operands[0].type & OT_BYTE &&
650  op->operands[1].type & OT_BYTE) {
651  data[i++] = 0xc0;
652  } else {
653  data[i++] = 0xc1;
654  }
655  if (op->operands[0].type & OT_REGALL &&
656  op->operands[1].type & OT_REGALL) { // TODO memory modes
657  data[i] |= 0xc0;
658  data[i] |= (op->operands[1].reg << 3);
659  data[i++] |= op->operands[0].reg;
660  }
661  return i;
662 }

References a, i, is_valid_registers, OT_BYTE, and OT_REGALL.

◆ opxchg()

static int opxchg ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 2774 of file asm_x86_nz.c.

2774  {
2776  int l = 0;
2777  int mod_byte = 0;
2778  int reg = 0;
2779  int rm = 0;
2780  st32 offset = 0;
2781 
2782  if (op->operands[0].type & OT_MEMORY || op->operands[1].type & OT_MEMORY) {
2783  data[l++] = 0x87;
2784  if (op->operands[0].type & OT_MEMORY) {
2785  rm = op->operands[0].regs[0];
2786  offset = op->operands[0].offset * op->operands[0].offset_sign;
2787  reg = op->operands[1].reg;
2788  } else if (op->operands[1].type & OT_MEMORY) {
2789  rm = op->operands[1].regs[0];
2790  offset = op->operands[1].offset * op->operands[1].offset_sign;
2791  reg = op->operands[0].reg;
2792  }
2793  if (offset) {
2794  mod_byte = 1;
2796  mod_byte = 2;
2797  }
2798  }
2799  } else {
2800  if (!((op->operands[0].type & ALL_SIZE) &
2801  (op->operands[1].type & ALL_SIZE))) { // unmatched operand sizes
2802  return -1;
2803  }
2804  if (op->operands[0].reg == X86R_EAX &&
2805  !op->operands[0].extended &&
2806  !(op->operands[0].type & OT_BYTE) &&
2807  op->operands[1].type & OT_GPREG) {
2808  if (op->operands[0].type & OT_WORD) {
2809  data[l++] = 0x66;
2810  } else if (op->operands[0].type & OT_DWORD &&
2811  op->operands[1].extended) {
2812  data[l++] = 0x41;
2813  } else if (op->operands[0].type & OT_QWORD) {
2814  if (op->operands[1].extended) {
2815  data[l++] = 0x49;
2816  } else {
2817  data[l++] = 0x48;
2818  }
2819  }
2820  data[l++] = 0x90 + op->operands[1].reg;
2821  return l;
2822  } else if (op->operands[1].reg == X86R_EAX &&
2823  !op->operands[1].extended &&
2824  !(op->operands[1].type & OT_BYTE) &&
2825  op->operands[0].type & OT_GPREG) {
2826  if (op->operands[1].type & OT_WORD) {
2827  data[l++] = 0x66;
2828  } else if (op->operands[1].type & OT_DWORD &&
2829  op->operands[0].extended) {
2830  data[l++] = 0x41;
2831  } else if (op->operands[1].type & OT_QWORD) {
2832  if (op->operands[0].extended) {
2833  data[l++] = 0x49;
2834  } else {
2835  data[l++] = 0x48;
2836  }
2837  }
2838  data[l++] = 0x90 + op->operands[0].reg;
2839  return l;
2840  } else if (op->operands[0].type & OT_GPREG &&
2841  op->operands[1].type & OT_GPREG) {
2842  if (op->operands[0].type & OT_WORD) {
2843  data[l++] = 0x66;
2844  }
2845  ut8 rex = 0x40 | op->operands[0].extended | op->operands[1].extended << 2 | !!(op->operands[0].type & OT_QWORD) << 3;
2846  if (rex != 0x40) {
2847  data[l++] = rex;
2848  }
2849  if (op->operands[0].type & OT_BYTE) {
2850  data[l++] = 0x86;
2851  } else {
2852  data[l++] = 0x87;
2853  }
2854  mod_byte = 3;
2855  reg = op->operands[1].reg;
2856  rm = op->operands[0].reg;
2857  }
2858  }
2859  data[l++] = mod_byte << 6 | reg << 3 | rm;
2860  if (mod_byte > 0 && mod_byte < 3) {
2861  data[l++] = offset;
2862  if (mod_byte == 2) {
2863  data[l++] = offset >> 8;
2864  data[l++] = offset >> 16;
2865  data[l++] = offset >> 24;
2866  }
2867  }
2868  return l;
2869 }

References ALL_SIZE, is_valid_registers, OT_BYTE, OT_DWORD, OT_GPREG, OT_MEMORY, OT_QWORD, OT_WORD, reg, st32, ST8_MAX, and X86R_EAX.

◆ opxor()

static int opxor ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 664 of file asm_x86_nz.c.

664  {
666  if (op->operands_count < 2) {
667  return -1;
668  }
669  if (op->operands[0].type == 0x80 && op->operands[0].reg == X86R_UNDEFINED) {
670  return -1;
671  }
672  if (op->operands[1].type == 0x80 && op->operands[0].reg == X86R_UNDEFINED) {
673  return -1;
674  }
675  if (op->operands[1].type & OT_CONSTANT) {
676  if (op->operands[0].type & OT_GPREG &&
677  op->operands[0].type & OT_WORD) {
678  return process_16bit_group_1(a, data, op, 0x30);
679  }
680  if (!is_al_reg(&op->operands[0])) {
681  return process_group_1(a, data, op);
682  }
683  }
684  return process_1byte_op(a, data, op, 0x30);
685 }

References a, is_al_reg(), is_valid_registers, OT_CONSTANT, OT_GPREG, OT_WORD, process_16bit_group_1(), process_1byte_op(), process_group_1(), and X86R_UNDEFINED.

◆ parse_segment_offset()

static void parse_segment_offset ( RzAsm a,
const char *  str,
size_t pos,
Operand op,
int  reg_index 
)
static

Definition at line 4851 of file asm_x86_nz.c.

4852  {
4853  int nextpos = *pos;
4854  char *c = strchr(str + nextpos, ':');
4855  if (c) {
4856  nextpos++; // Skip the ':'
4857  c = strchr(str + nextpos, '[');
4858  if (c) {
4859  nextpos++;
4860  } // Skip the '['
4861 
4862  // Assign registers to match behaviour of OT_MEMORY type
4863  op->regs[reg_index] = op->reg;
4864  op->type |= OT_MEMORY;
4865  op->offset_sign = 1;
4866  char *p = strchr(str + nextpos, '-');
4867  if (p) {
4868  op->offset_sign = -1;
4869  nextpos++;
4870  }
4871  op->scale[reg_index] = getnum(a, str + nextpos);
4872  op->offset = op->scale[reg_index];
4873  }
4874 }
static ut64 getnum(RzAsm *a, const char *s)
Definition: asm_x86_nz.c:5139
void * p
Definition: libc.cpp:67
#define c(i)
Definition: sha256.c:43
int pos
Definition: main.c:11

References a, c, getnum(), OT_MEMORY, p, pos, and cmd_descs_generate::str.

Referenced by parseOperand().

◆ parseOpcode()

static int parseOpcode ( RzAsm a,
const char *  op,
Opcode out 
)
static

Definition at line 5095 of file asm_x86_nz.c.

5095  {
5096  out->has_bnd = false;
5097  bool isrepop = false;
5098  if (!strncmp(op, "bnd ", 4)) {
5099  out->has_bnd = true;
5100  op += 4;
5101  }
5102  char *args = strchr(op, ' ');
5103  out->mnemonic = args ? rz_str_ndup(op, args - op) : strdup(op);
5104  out->operands[0].type = out->operands[1].type = 0;
5105  out->operands[0].extended = out->operands[1].extended = false;
5106  out->operands[0].reg = out->operands[0].regs[0] = out->operands[0].regs[1] = X86R_UNDEFINED;
5107  out->operands[1].reg = out->operands[1].regs[0] = out->operands[1].regs[1] = X86R_UNDEFINED;
5108  out->operands[0].immediate = out->operands[1].immediate = 0;
5109  out->operands[0].sign = out->operands[1].sign = 1;
5110  out->operands[0].is_good_flag = out->operands[1].is_good_flag = true;
5111  out->is_short = false;
5112  out->operands_count = 0;
5113  if (args) {
5114  args++;
5115  } else {
5116  return 1;
5117  }
5118  if (!rz_str_ncasecmp(args, "short", 5)) {
5119  out->is_short = true;
5120  args += 5;
5121  }
5122  if (!strncmp(out->mnemonic, "rep", 3)) {
5123  isrepop = true;
5124  }
5125  parseOperand(a, args, &(out->operands[0]), isrepop);
5126  out->operands_count = 1;
5127  while (out->operands_count < MAX_OPERANDS) {
5128  args = strchr(args, ',');
5129  if (!args) {
5130  break;
5131  }
5132  args++;
5133  parseOperand(a, args, &(out->operands[out->operands_count]), isrepop);
5134  out->operands_count++;
5135  }
5136  return 0;
5137 }
static int parseOperand(RzAsm *a, const char *str, Operand *op, bool isrepop)
Definition: asm_x86_nz.c:4876
#define MAX_OPERANDS
Definition: asm_x86_nz.c:76
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int args
Definition: mipsasm.c:18
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006

References a, args, MAX_OPERANDS, out, parseOperand(), rz_str_ncasecmp(), rz_str_ndup(), strdup(), and X86R_UNDEFINED.

Referenced by assemble(), and oprep().

◆ parseOperand()

static int parseOperand ( RzAsm a,
const char *  str,
Operand op,
bool  isrepop 
)
static

Definition at line 4876 of file asm_x86_nz.c.

4876  {
4877  size_t pos, nextpos = 0;
4879  int size_token = 1;
4880  bool explicit_size = false;
4881  int reg_index = 0;
4882  // Reset type
4883  op->type = 0;
4884  // Consume tokens denoting the operand size
4885  while (size_token) {
4886  pos = nextpos;
4887  last_type = getToken(str, &pos, &nextpos);
4888 
4889  // Token may indicate size: then skip
4890  if (!rz_str_ncasecmp(str + pos, "ptr", 3)) {
4891  continue;
4892  } else if (!rz_str_ncasecmp(str + pos, "byte", 4)) {
4893  op->type |= OT_MEMORY | OT_BYTE;
4894  op->dest_size = OT_BYTE;
4895  explicit_size = true;
4896  } else if (!rz_str_ncasecmp(str + pos, "word", 4)) {
4897  op->type |= OT_MEMORY | OT_WORD;
4898  op->dest_size = OT_WORD;
4899  explicit_size = true;
4900  } else if (!rz_str_ncasecmp(str + pos, "dword", 5)) {
4901  op->type |= OT_MEMORY | OT_DWORD;
4902  op->dest_size = OT_DWORD;
4903  explicit_size = true;
4904  } else if (!rz_str_ncasecmp(str + pos, "qword", 5)) {
4905  op->type |= OT_MEMORY | OT_QWORD;
4906  op->dest_size = OT_QWORD;
4907  explicit_size = true;
4908  } else if (!rz_str_ncasecmp(str + pos, "oword", 5)) {
4909  op->type |= OT_MEMORY | OT_OWORD;
4910  op->dest_size = OT_OWORD;
4911  explicit_size = true;
4912  } else if (!rz_str_ncasecmp(str + pos, "tbyte", 5)) {
4913  op->type |= OT_MEMORY | OT_TBYTE;
4914  op->dest_size = OT_TBYTE;
4915  explicit_size = true;
4916  } else { // the current token doesn't denote a size
4917  size_token = 0;
4918  }
4919  }
4920 
4921  // Next token: register, immediate, or '['
4922  if (str[pos] == '[') {
4923  // Don't care about size, if none is given.
4924  if (!op->type) {
4925  op->type = OT_MEMORY;
4926  }
4927  // At the moment, we only accept plain linear combinations:
4928  // part := address | [factor *] register
4929  // address := part {+ part}*
4930  op->offset = op->scale[0] = op->scale[1] = 0;
4931 
4932  ut64 temp = 1;
4934  bool first_reg = true;
4935  while (str[pos] != ']') {
4936  if (pos > nextpos) {
4937  // RZ_LOG_ERROR("assembler: x86.nz: failed to parse instruction\n");
4938  break;
4939  }
4940  pos = nextpos;
4941  if (!str[pos]) {
4942  break;
4943  }
4944  last_type = getToken(str, &pos, &nextpos);
4945 
4946  if (last_type == TT_SPECIAL) {
4947  if (str[pos] == '+' || str[pos] == '-' || str[pos] == ']') {
4948  if (reg != X86R_UNDEFINED) {
4949  if (reg_index < 2) {
4950  op->regs[reg_index] = reg;
4951  op->scale[reg_index] = temp;
4952  }
4953  ++reg_index;
4954  } else {
4955  op->offset += temp;
4956  if (reg_index < 2) {
4957  op->regs[reg_index] = X86R_UNDEFINED;
4958  }
4959  }
4960  temp = 1;
4961  reg = X86R_UNDEFINED;
4962  } else if (str[pos] == '*') {
4963  // go to ], + or - to get scale
4964 
4965  // Something to do here?
4966  // Seems we are just ignoring '*' or assuming it implicitly.
4967  }
4968  } else if (last_type == TT_WORD) {
4969  ut32 reg_type = 0;
4970 
4971  // We can't multiply registers
4972  if (reg != X86R_UNDEFINED) {
4973  op->type = 0; // Make the result invalid
4974  }
4975 
4976  // Reset nextpos: parseReg wants to parse from the beginning
4977  nextpos = pos;
4978  reg = parseReg(a, str, &nextpos, &reg_type);
4979 
4980  if (first_reg) {
4981  op->extended = false;
4982  if (reg > 8) {
4983  op->extended = true;
4984  op->reg = reg - 9;
4985  } else {
4986  op->reg = reg;
4987  }
4988  first_reg = false;
4989  } else if (reg > 8) {
4990  op->reg = reg - 9;
4991  }
4992  if (reg_type & OT_REGTYPE & OT_SEGMENTREG) {
4993  op->reg = reg;
4994  op->type = reg_type;
4995  parse_segment_offset(a, str, &nextpos, op, reg_index);
4996  return nextpos;
4997  }
4998 
4999  // Still going to need to know the size if not specified
5000  if (!explicit_size) {
5001  op->type |= reg_type;
5002  }
5003  op->reg_size = reg_type;
5004  op->explicit_size = explicit_size;
5005 
5006  // Addressing only via general purpose registers
5007  if (!(reg_type & OT_GPREG)) {
5008  op->type = 0; // Make the result invalid
5009  }
5010  } else {
5011  char *p = strchr(str, '+');
5012  op->offset_sign = 1;
5013  if (!p) {
5014  p = strchr(str, '-');
5015  if (p) {
5016  op->offset_sign = -1;
5017  }
5018  }
5019  // with SIB notation, we need to consider the right sign
5020  char *plus = strchr(str, '+');
5021  char *minus = strchr(str, '-');
5022  char *closeB = strchr(str, ']');
5023  if (plus && minus && plus < closeB && minus < closeB) {
5024  op->offset_sign = -1;
5025  }
5026  // If there's a scale, we don't want to parse out the
5027  // scale with the offset (scale + offset) otherwise the scale
5028  // will be the sum of the two. This splits the numbers
5029  char *tmp;
5030  tmp = malloc(strlen(str + pos) + 1);
5031  strcpy(tmp, str + pos);
5032  strtok(tmp, "+-");
5033  st64 read = getnum(a, tmp);
5034  free(tmp);
5035  temp *= read;
5036  }
5037  }
5038  } else if (last_type == TT_WORD) { // register
5039  nextpos = pos;
5040 
5041  if (isrepop) {
5042  op->is_good_flag = false;
5043  strncpy(op->rep_op, str, MAX_REPOP_LENGTH - 1);
5044  op->rep_op[MAX_REPOP_LENGTH - 1] = '\0';
5045  return nextpos;
5046  }
5047 
5048  op->reg = parseReg(a, str, &nextpos, &op->type);
5049 
5050  op->extended = false;
5051  if (op->reg > 8) {
5052  op->extended = true;
5053  op->reg -= 9;
5054  }
5055  if (op->type & OT_REGTYPE & OT_SEGMENTREG) {
5056  parse_segment_offset(a, str, &nextpos, op, reg_index);
5057  return nextpos;
5058  }
5059  if (op->reg == X86R_UNDEFINED) {
5060  op->is_good_flag = false;
5061  if (a->num && a->num->value == 0) {
5062  return nextpos;
5063  }
5064  op->type = OT_CONSTANT;
5065  RzCore *core = a->num ? (RzCore *)(a->num->userptr) : NULL;
5066  if (core && rz_flag_get(core->flags, str)) {
5067  op->is_good_flag = true;
5068  }
5069 
5070  char *p = strchr(str, '-');
5071  if (p) {
5072  op->sign = -1;
5073  str = ++p;
5074  }
5075  op->immediate = getnum(a, str);
5076  } else if (op->reg < X86R_UNDEFINED) {
5077  strncpy(op->rep_op, str, MAX_REPOP_LENGTH - 1);
5078  op->rep_op[MAX_REPOP_LENGTH - 1] = '\0';
5079  }
5080  } else { // immediate
5081  // We don't know the size, so let's just set no size flag.
5082  op->type = OT_CONSTANT;
5083  op->sign = 1;
5084  char *p = strchr(str, '-');
5085  if (p) {
5086  op->sign = -1;
5087  str = ++p;
5088  }
5089  op->immediate = getnum(a, str);
5090  }
5091 
5092  return nextpos;
5093 }
static enum map_type last_type
Definition: aarch64-dis.c:45
static x86newTokenType getToken(const char *str, size_t *begin, size_t *end)
Definition: asm_x86_nz.c:4625
#define OT_OWORD
Definition: asm_x86_nz.c:53
static Register parseReg(RzAsm *a, const char *str, size_t *pos, ut32 *type)
Definition: asm_x86_nz.c:4711
#define MAX_REPOP_LENGTH
Definition: asm_x86_nz.c:77
static void parse_segment_offset(RzAsm *a, const char *str, size_t *pos, Operand *op, int reg_index)
Definition: asm_x86_nz.c:4851
#define NULL
Definition: cris-opc.c:27
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
Definition: flag.c:310
void * malloc(size_t size)
Definition: malloc.c:123
RzFlag * flags
Definition: rz_core.h:330
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115

References a, rz_core_t::flags, free(), getnum(), getToken(), last_type, malloc(), MAX_REPOP_LENGTH, NULL, OT_BYTE, OT_CONSTANT, OT_DWORD, OT_GPREG, OT_MEMORY, OT_OWORD, OT_QWORD, OT_REGTYPE, OT_SEGMENTREG, OT_TBYTE, OT_WORD, p, parse_segment_offset(), parseReg(), pos, read(), reg, rz_flag_get(), rz_str_ncasecmp(), st64, cmd_descs_generate::str, autogen_x86imm::tmp, TT_SPECIAL, TT_WORD, ut64(), and X86R_UNDEFINED.

Referenced by parseOpcode().

◆ parseReg()

static Register parseReg ( RzAsm a,
const char *  str,
size_t pos,
ut32 type 
)
static

Get the register at position pos in str. Increase pos afterwards.

Definition at line 4711 of file asm_x86_nz.c.

4711  {
4712  int i;
4713  // Must be the same order as in enum register_t
4714  const char *regs[] = { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "eip", NULL };
4715  const char *regsext[] = { "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d", NULL };
4716  const char *regs8[] = { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", NULL };
4717  const char *regs16[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", NULL };
4718  const char *regs64[] = { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "rip", NULL };
4719  const char *regs64ext[] = { "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", NULL };
4720  const char *sregs[] = { "es", "cs", "ss", "ds", "fs", "gs", NULL };
4721  const char *cregs[] = { "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", NULL };
4722  const char *dregs[] = { "dr0", "dr1", "dr2", "dr3", "dr4", "dr5", "dr6", "dr7", NULL };
4723 
4724  // Get token (especially the length)
4725  size_t nextpos, length;
4726  const char *token;
4727  getToken(str, pos, &nextpos);
4728  token = str + *pos;
4729  length = nextpos - *pos;
4730  *pos = nextpos;
4731 
4732  // General purpose registers
4733  if (length == 3 && token[0] == 'e') {
4734  for (i = 0; regs[i]; i++) {
4735  if (!rz_str_ncasecmp(regs[i], token, length)) {
4736  *type = (OT_GPREG & OT_REG(i)) | OT_DWORD;
4737  return i;
4738  }
4739  }
4740  }
4741  // Control registers
4742  if (length == 3 && token[0] == 'c') {
4743  for (i = 0; cregs[i]; i++) {
4744  if (!rz_str_ncasecmp(cregs[i], token, length)) {
4745  *type = (OT_CONTROLREG & OT_REG(i)) | OT_DWORD;
4746  return i;
4747  }
4748  }
4749  }
4750  // Debug registers
4751  if (length == 3 && token[0] == 'd') {
4752  for (i = 0; cregs[i]; i++) {
4753  if (!rz_str_ncasecmp(dregs[i], token, length)) {
4754  *type = (OT_DEBUGREG & OT_REG(i)) | OT_DWORD;
4755  return i;
4756  }
4757  }
4758  }
4759  if (length == 2) {
4760  if (token[1] == 'l' || token[1] == 'h') {
4761  for (i = 0; regs8[i]; i++) {
4762  if (!rz_str_ncasecmp(regs8[i], token, length)) {
4763  *type = (OT_GPREG & OT_REG(i)) | OT_BYTE;
4764  return i;
4765  }
4766  }
4767  }
4768  for (i = 0; regs16[i]; i++) {
4769  if (!rz_str_ncasecmp(regs16[i], token, length)) {
4770  *type = (OT_GPREG & OT_REG(i)) | OT_WORD;
4771  return i;
4772  }
4773  }
4774  // This isn't working properly yet
4775  for (i = 0; sregs[i]; i++) {
4776  if (!rz_str_ncasecmp(sregs[i], token, length)) {
4777  *type = (OT_SEGMENTREG & OT_REG(i)) | OT_WORD;
4778  return i;
4779  }
4780  }
4781  }
4782  if (token[0] == 'r') {
4783  for (i = 0; regs64[i]; i++) {
4784  if (!rz_str_ncasecmp(regs64[i], token, length)) {
4785  *type = (OT_GPREG & OT_REG(i)) | OT_QWORD;
4786  a->bits = 64;
4787  return i;
4788  }
4789  }
4790  for (i = 0; regs64ext[i]; i++) {
4791  if (!rz_str_ncasecmp(regs64ext[i], token, length)) {
4792  *type = (OT_GPREG & OT_REG(i)) | OT_QWORD;
4793  a->bits = 64;
4794  return i + 9;
4795  }
4796  }
4797  for (i = 0; regsext[i]; i++) {
4798  if (!rz_str_ncasecmp(regsext[i], token, length)) {
4799  *type = (OT_GPREG & OT_REG(i)) | OT_DWORD;
4800  if (a->bits < 32) {
4801  a->bits = 32;
4802  }
4803  return i + 9;
4804  }
4805  }
4806  }
4807  // Extended registers
4808  if (is_st_register(token)) {
4809  *type = (OT_FPUREG & ~OT_REGALL);
4810  *pos = 2;
4811  }
4812  if (is_mm_register(token)) {
4813  *type = (OT_MMXREG & ~OT_REGALL);
4814  *pos = 2;
4815  }
4816  if (is_xmm_register(token)) {
4817  *type = (OT_XMMREG & ~OT_REGALL);
4818  *pos = 3;
4819  }
4820  // Now read number, possibly with parentheses
4821  if (*type & (OT_FPUREG | OT_MMXREG | OT_XMMREG) & ~OT_REGALL) {
4823  // pass by '(',if there is one
4824  if (getToken(token, pos, &nextpos) == TT_SPECIAL && token[*pos] == '(') {
4825  *pos = nextpos;
4826  }
4827  // read number
4828  // const int maxreg = (a->bits == 64) ? 15 : 7;
4829  if (getToken(token, pos, &nextpos) != TT_NUMBER) {
4830  RZ_LOG_ERROR("assembler: x86.nz: expected register number but found '%s'\n", str + *pos);
4831  return X86R_UNDEFINED;
4832  }
4833  reg = getnum(a, token + *pos);
4834  // st and mm go up to 7, xmm up to 15
4835  if ((reg > 15) || ((*type & (OT_FPUREG | OT_MMXREG) & ~OT_REGALL) && reg > 7)) {
4836  RZ_LOG_ERROR("assembler: x86.nz: register index is too large\n");
4837  return X86R_UNDEFINED;
4838  }
4839  *pos = nextpos;
4840 
4841  // pass by ')'
4842  if (getToken(token, pos, &nextpos) == TT_SPECIAL && token[*pos] == ')') {
4843  *pos = nextpos;
4844  }
4845  *type |= (OT_REG(reg) & ~OT_REGTYPE);
4846  return reg;
4847  }
4848  return X86R_UNDEFINED;
4849 }
static char * regs[]
Definition: analysis_sh.c:203
#define OT_REG(num)
Definition: asm_x86_nz.c:46
static bool is_st_register(const char *token)
Definition: asm_x86_nz.c:4687
#define OT_XMMREG
Definition: asm_x86_nz.c:37
#define OT_MMXREG
Definition: asm_x86_nz.c:36
static bool is_xmm_register(const char *token)
Definition: asm_x86_nz.c:4657
static bool is_mm_register(const char *token)
Definition: asm_x86_nz.c:4666
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
int type
Definition: mipsasm.c:17

References a, getnum(), getToken(), i, is_mm_register(), is_st_register(), is_xmm_register(), length, NULL, OT_BYTE, OT_CONTROLREG, OT_DEBUGREG, OT_DWORD, OT_FPUREG, OT_GPREG, OT_MMXREG, OT_QWORD, OT_REG, OT_REGALL, OT_REGTYPE, OT_SEGMENTREG, OT_WORD, OT_XMMREG, pos, reg, regs, RZ_LOG_ERROR, rz_str_ncasecmp(), cmd_descs_generate::str, TT_NUMBER, TT_SPECIAL, type, and X86R_UNDEFINED.

Referenced by parseOperand().

◆ process_16bit_group_1()

static int process_16bit_group_1 ( RzAsm a,
ut8 data,
const Opcode op,
int  op1 
)
static

Definition at line 221 of file asm_x86_nz.c.

221  {
223  int l = 0;
224  int immediate = op->operands[1].immediate * op->operands[1].sign;
225 
226  data[l++] = 0x66;
227  if (op->operands[1].immediate < 128) {
228  data[l++] = 0x83;
229  data[l++] = op->operands[0].reg | (0xc0 + op1 + op->operands[0].reg);
230  } else {
231  if (op->operands[0].reg == X86R_AX) {
232  data[l++] = 0x05 + op1;
233  } else {
234  data[l++] = 0x81;
235  data[l++] = (0xc0 + op1) | op->operands[0].reg;
236  }
237  }
238  data[l++] = immediate;
239  if (op->operands[1].immediate > 127) {
240  data[l++] = immediate >> 8;
241  }
242 
243  return l;
244 }

References is_valid_registers, and X86R_AX.

Referenced by opadc(), opadd(), opand(), opcmp(), opor(), opsbb(), opsub(), and opxor().

◆ process_1byte_op()

static int process_1byte_op ( RzAsm a,
ut8 data,
const Opcode op,
int  op1 
)
static

Definition at line 414 of file asm_x86_nz.c.

414  {
416  int l = 0;
417  int mod_byte = 0;
418  int reg = 0;
419  int rm = 0;
420  int rex = 0;
421  int mem_ref = 0;
422  st32 offset = 0;
423  int ebp_reg = 0;
424 
425  if (!op->operands[1].is_good_flag) {
426  return -1;
427  }
428 
429  if (op->operands[0].reg == X86R_AL && op->operands[1].type & OT_CONSTANT) {
430  data[l++] = op1 + 4;
431  data[l++] = op->operands[1].immediate * op->operands[1].sign;
432  return l;
433  }
434 
435  if (a->bits == 64) {
436  if (!(op->operands[0].type & op->operands[1].type)) {
437  return -1;
438  }
439  }
440 
441  if (a->bits == 64 && ((op->operands[0].type & OT_QWORD) | (op->operands[1].type & OT_QWORD))) {
442  if (op->operands[0].extended) {
443  rex = 1;
444  }
445  if (op->operands[1].extended) {
446  rex += 4;
447  }
448  data[l++] = 0x48 | rex;
449  }
450 
451  if (op->operands[0].type & OT_MEMORY && op->operands[1].type & OT_REGALL) {
452  if (a->bits == 64 && (op->operands[0].type & OT_DWORD) &&
453  (op->operands[1].type & OT_DWORD)) {
454  data[l++] = 0x67;
455  }
456  if (op->operands[0].type & OT_BYTE && op->operands[1].type & OT_BYTE) {
457  data[l++] = op1;
458  } else if (op->operands[0].type & (OT_DWORD | OT_QWORD) &&
459  op->operands[1].type & (OT_DWORD | OT_QWORD)) {
460  data[l++] = op1 + 0x1;
461  } else {
462  RZ_LOG_ERROR("assembler: x86.nz: %s: mismatched operand sizes\n", op->mnemonic);
463  return -1;
464  }
465  reg = op->operands[1].reg;
466  rm = op->operands[0].regs[0];
467  offset = op->operands[0].offset * op->operands[0].offset_sign;
468  if (rm == -1) {
469  rm = 5;
470  mem_ref = 1;
471  } else {
472  if (offset) {
473  mod_byte = 1;
475  mod_byte = 2;
476  }
477  } else if (op->operands[0].regs[1] != X86R_UNDEFINED) {
478  rm = 4;
479  offset = op->operands[0].regs[1] << 3;
480  }
481  }
482  } else if (op->operands[0].type & OT_REGALL) {
483  if (op->operands[1].type & OT_MEMORY) {
484  if (op->operands[0].type & OT_BYTE && op->operands[1].type & OT_BYTE) {
485  data[l++] = op1 + 0x2;
486  } else if (op->operands[0].type & (OT_DWORD | OT_QWORD) &&
487  op->operands[1].type & (OT_DWORD | OT_QWORD)) {
488  data[l++] = op1 + 0x3;
489  } else {
490  RZ_LOG_ERROR("assembler: x86.nz: %s: mismatched operand sizes\n", op->mnemonic);
491  return -1;
492  }
493  reg = op->operands[0].reg;
494  rm = op->operands[1].regs[0];
495 
496  if (op->operands[1].scale[0] > 1) {
497  if (op->operands[1].regs[1] != X86R_UNDEFINED) {
498  data[l++] = op->operands[0].reg << 3 | 4;
499  data[l++] = getsib(op->operands[1].scale[0]) << 6 |
500  op->operands[1].regs[0] << 3 |
501  op->operands[1].regs[1];
502  return l;
503  }
504  data[l++] = op->operands[0].reg << 3 | 4; // 4 = SIB
505  data[l++] = getsib(op->operands[1].scale[0]) << 6 | op->operands[1].regs[0] << 3 | 5;
506  data[l++] = op->operands[1].offset * op->operands[1].offset_sign;
507  data[l++] = 0;
508  data[l++] = 0;
509  data[l++] = 0;
510  return l;
511  }
512  offset = op->operands[1].offset * op->operands[1].offset_sign;
513  if (offset) {
514  mod_byte = 1;
516  mod_byte = 2;
517  }
518  }
519 
520  } else if (op->operands[1].type & OT_REGALL) {
521  if (op->operands[0].type & OT_BYTE && op->operands[1].type & OT_BYTE) {
522  data[l++] = op1;
523  } else if (op->operands[0].type & OT_DWORD && op->operands[1].type & OT_DWORD) {
524  data[l++] = op1 + 0x1;
525  }
526  if (a->bits == 64) {
527  if (op->operands[0].type & OT_QWORD &&
528  op->operands[1].type & OT_QWORD) {
529  data[l++] = op1 + 0x1;
530  }
531  }
532 
533  mod_byte = 3;
534  reg = op->operands[1].reg;
535  rm = op->operands[0].reg;
536  }
537  }
538  if (op->operands[0].regs[0] == X86R_EBP ||
539  op->operands[1].regs[0] == X86R_EBP) {
540  // reg += 8;
541  ebp_reg = 1;
542  }
543  data[l++] = mod_byte << 6 | reg << 3 | rm;
544 
545  if (op->operands[0].regs[0] == X86R_ESP ||
546  op->operands[1].regs[0] == X86R_ESP) {
547  data[l++] = 0x24;
548  }
549  if (offset || mem_ref || ebp_reg) {
550  // if ((mod_byte > 0 && mod_byte < 3) || mem_ref) {
551  data[l++] = offset;
552  if (mod_byte == 2 || mem_ref) {
553  data[l++] = offset >> 8;
554  data[l++] = offset >> 16;
555  data[l++] = offset >> 24;
556  }
557  }
558  return l;
559 }

References a, getsib(), is_valid_registers, OT_BYTE, OT_CONSTANT, OT_DWORD, OT_MEMORY, OT_QWORD, OT_REGALL, reg, RZ_LOG_ERROR, st32, ST8_MAX, X86R_AL, X86R_EBP, X86R_ESP, and X86R_UNDEFINED.

Referenced by opadc(), opadd(), opand(), opcmp(), opor(), opsbb(), opsub(), and opxor().

◆ process_group_1()

static int process_group_1 ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 246 of file asm_x86_nz.c.

246  {
248  int l = 0;
249  int modrm = 0;
250  int mod_byte = 0;
251  int offset = 0;
252  int mem_ref = 0;
253  st32 immediate = 0;
254 
255  if (!op->operands[1].is_good_flag) {
256  return -1;
257  }
258  if (a->bits == 64 && op->operands[0].type & OT_QWORD) {
259  data[l++] = 0x48;
260  }
261  if (!strcmp(op->mnemonic, "adc")) {
262  modrm = 2;
263  } else if (!strcmp(op->mnemonic, "add")) {
264  modrm = 0;
265  } else if (!strcmp(op->mnemonic, "or")) {
266  modrm = 1;
267  } else if (!strcmp(op->mnemonic, "and")) {
268  modrm = 4;
269  } else if (!strcmp(op->mnemonic, "xor")) {
270  modrm = 6;
271  } else if (!strcmp(op->mnemonic, "sbb")) {
272  modrm = 3;
273  } else if (!strcmp(op->mnemonic, "sub")) {
274  modrm = 5;
275  } else if (!strcmp(op->mnemonic, "cmp")) {
276  modrm = 7;
277  }
278  immediate = op->operands[1].immediate * op->operands[1].sign;
279 
280  if (op->operands[0].type & OT_DWORD ||
281  op->operands[0].type & OT_QWORD) {
282  if (op->operands[1].immediate < 128) {
283  data[l++] = 0x83;
284  } else if (op->operands[0].reg != X86R_EAX ||
285  op->operands[0].type & OT_MEMORY) {
286  data[l++] = 0x81;
287  }
288  } else if (op->operands[0].type & OT_BYTE) {
289  if (op->operands[1].immediate > 255) {
290  RZ_LOG_ERROR("assembler: x86.nz: %s: the immediate value exceeds bounds (imm > 255)\n", op->mnemonic);
291  return -1;
292  }
293  data[l++] = 0x80;
294  }
295  if (op->operands[0].type & OT_MEMORY) {
296  offset = op->operands[0].offset * op->operands[0].offset_sign;
297  if (op->operands[0].offset || op->operands[0].regs[0] == X86R_EBP) {
298  mod_byte = 1;
299  }
301  mod_byte = 2;
302  }
303  int reg0 = op->operands[0].regs[0];
304  if (reg0 == -1) {
305  mem_ref = 1;
306  reg0 = 5;
307  mod_byte = 0;
308  }
309  data[l++] = mod_byte << 6 | modrm << 3 | reg0;
310  if (op->operands[0].regs[0] == X86R_ESP) {
311  data[l++] = 0x24;
312  }
313  if (mod_byte || mem_ref) {
314  data[l++] = offset;
315  if (mod_byte == 2 || mem_ref) {
316  data[l++] = offset >> 8;
317  data[l++] = offset >> 16;
318  data[l++] = offset >> 24;
319  }
320  }
321  } else {
322  if (op->operands[1].immediate > 127 && op->operands[0].reg == X86R_EAX) {
323  data[l++] = 5 | modrm << 3 | op->operands[0].reg;
324  } else {
325  mod_byte = 3;
326  data[l++] = mod_byte << 6 | modrm << 3 | op->operands[0].reg;
327  }
328  }
329 
330  data[l++] = immediate;
331  if ((immediate > 127 || immediate < -128) &&
332  ((op->operands[0].type & OT_DWORD) || (op->operands[0].type & OT_QWORD))) {
333  data[l++] = immediate >> 8;
334  data[l++] = immediate >> 16;
335  data[l++] = immediate >> 24;
336  }
337  return l;
338 }

References a, is_valid_registers, OT_BYTE, OT_DWORD, OT_MEMORY, OT_QWORD, RZ_LOG_ERROR, st32, ST8_MAX, X86R_EAX, X86R_EBP, and X86R_ESP.

Referenced by opadc(), opadd(), opand(), opcmp(), opor(), opsbb(), opsub(), and opxor().

◆ process_group_2()

static int process_group_2 ( RzAsm a,
ut8 data,
const Opcode op 
)
static

Definition at line 340 of file asm_x86_nz.c.

340  {
342  int l = 0;
343  int modrm = 0;
344  int mod_byte = 0;
345  int reg0 = 0;
346 
347  if (a->bits == 64 && op->operands[0].type & OT_QWORD) {
348  data[l++] = 0x48;
349  }
350 
351  if (!strcmp(op->mnemonic, "rol")) {
352  modrm = 0;
353  } else if (!strcmp(op->mnemonic, "ror")) {
354  modrm = 1;
355  } else if (!strcmp(op->mnemonic, "rcl")) {
356  modrm = 2;
357  } else if (!strcmp(op->mnemonic, "rcr")) {
358  modrm = 3;
359  } else if (!strcmp(op->mnemonic, "shl")) {
360  modrm = 4;
361  } else if (!strcmp(op->mnemonic, "shr")) {
362  modrm = 5;
363  } else if (!strcmp(op->mnemonic, "sal")) {
364  modrm = 6;
365  } else if (!strcmp(op->mnemonic, "sar")) {
366  modrm = 7;
367  }
368 
369  st32 immediate = op->operands[1].immediate * op->operands[1].sign;
370  if (immediate > 255 || immediate < -128) {
371  RZ_LOG_ERROR("assembler: x86.nz: %s: the immediate value exceeds bounds (imm > 255 or imm < -128)\n", op->mnemonic);
372  return -1;
373  }
374 
375  if (op->operands[0].type & (OT_DWORD | OT_QWORD)) {
376  if (op->operands[1].type & (OT_GPREG | OT_BYTE)) {
377  data[l++] = 0xd3;
378  } else if (immediate == 1) {
379  data[l++] = 0xd1;
380  } else {
381  data[l++] = 0xc1;
382  }
383  } else if (op->operands[0].type & OT_BYTE) {
384  const Operand *o = &op->operands[0];
385  if (o->regs[0] != -1 && o->regs[1] != -1) {
386  data[l++] = 0xc0;
387  data[l++] = 0x44;
388  data[l++] = o->regs[0] | (o->regs[1] << 3);
389  data[l++] = (ut8)((o->offset * o->offset_sign) & 0xff);
390  data[l++] = immediate;
391  return l;
392  } else if (op->operands[1].type & (OT_GPREG | OT_WORD)) {
393  data[l++] = 0xd2;
394  } else if (immediate == 1) {
395  data[l++] = 0xd0;
396  } else {
397  data[l++] = 0xc0;
398  }
399  }
400  if (op->operands[0].type & OT_MEMORY) {
401  reg0 = op->operands[0].regs[0];
402  mod_byte = 0;
403  } else {
404  reg0 = op->operands[0].reg;
405  mod_byte = 3;
406  }
407  data[l++] = mod_byte << 6 | modrm << 3 | reg0;
408  if (immediate != 1 && !(op->operands[1].type & OT_GPREG)) {
409  data[l++] = immediate;
410  }
411  return l;
412 }
st8 offset_sign
Definition: asm_x86_nz.c:170
ut64 offset
Definition: asm_x86_nz.c:169
Register regs[2]
Definition: asm_x86_nz.c:171

References a, is_valid_registers, operand_t::offset, operand_t::offset_sign, OT_BYTE, OT_DWORD, OT_GPREG, OT_MEMORY, OT_QWORD, OT_WORD, operand_t::regs, RZ_LOG_ERROR, st32, and ut8.

Variable Documentation

◆ oplookup

LookupTable oplookup[]

Definition at line 4268 of file asm_x86_nz.c.

Referenced by assemble(), and oprep().

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_ASM,
}
RzAsmPlugin rz_asm_plugin_x86_nz
Definition: asm_x86_nz.c:5249
@ RZ_LIB_TYPE_ASM
Definition: rz_lib.h:72
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_asm.h:133

Definition at line 5260 of file asm_x86_nz.c.

◆ rz_asm_plugin_x86_nz

RzAsmPlugin rz_asm_plugin_x86_nz
Initial value:
= {
.name = "x86.nz",
.desc = "x86 handmade assembler",
.license = "LGPL3",
.arch = "x86",
.bits = 16 | 32 | 64,
.assemble = &assemble
}
static int assemble(RzAsm *a, RzAsmOp *ao, const char *str)
Definition: asm_x86_nz.c:5202
#define RZ_SYS_ENDIAN_LITTLE
Definition: rz_types.h:526

Definition at line 5249 of file asm_x86_nz.c.

◆ SEG_REG_PREFIXES

const ut8 SEG_REG_PREFIXES[] = { 0x26, 0x2e, 0x36, 0x3e, 0x64, 0x65 }

Definition at line 83 of file asm_x86_nz.c.

Referenced by opmov().