structures.
Add more interface functions to isolate structure internals and make it
easier to add warnings (such as for multiple overrides/prefixes).
svn path=/trunk/yasm/; revision=43
-/* $Id: bytecode.h,v 1.6 2001/05/30 07:07:16 peter Exp $
+/* $Id: bytecode.h,v 1.7 2001/05/30 07:41:03 peter Exp $
* Bytecode utility functions header file
*
* Copyright (C) 2001 Peter Johnson
#define _BYTECODE_H_
typedef struct effaddr_s {
- unsigned long offset;
- unsigned char len; /* length of offset (in bytes), 0 if none */
- unsigned char addrsize; /* 16 or 32, 0 indicates no override */
+ unsigned long disp; /* address displacement */
+ unsigned char len; /* length of disp (in bytes), 0 if none */
+
unsigned char segment; /* segment override, 0 if none */
+
unsigned char modrm;
+ unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
+
unsigned char sib;
+ unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
} effaddr;
typedef struct immval_s {
unsigned long val;
+
unsigned char len; /* length of val (in bytes), 0 if none */
unsigned char isrel;
unsigned char isneg; /* the value has been explicitly negated */
+
+ unsigned char f_len; /* final imm length */
+ unsigned char f_rel; /* 1 if final imm should be rel */
+ unsigned char f_sign; /* 1 if final imm should be signed */
} immval;
typedef struct bytecode_s {
effaddr ea; /* effective address */
immval imm; /* immediate or relative value */
- unsigned char f_len_imm; /* final imm length */
- unsigned char f_rel_imm; /* 1 if final imm should be rel */
- unsigned char f_sign_imm; /* 1 if final imm should be signed */
unsigned char opcode[3]; /* opcode */
unsigned char opcode_len;
+ unsigned char addrsize; /* 0 indicates no override */
unsigned char opersize; /* 0 indicates no override */
unsigned char lockrep_pre; /* 0 indicates no prefix */
} insn;
immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
void SetEASegment(effaddr *ptr, unsigned char segment);
-void SetEAAddressSize(effaddr *ptr, unsigned char addrsize, unsigned char len);
+void SetEALen(effaddr *ptr, unsigned char len);
+
+void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
+void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
+void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
void BuildBC_Insn(bytecode *bc,
unsigned char opersize,
-/* $Id: bytecode.c,v 1.7 2001/05/30 07:07:16 peter Exp $
+/* $Id: bytecode.c,v 1.8 2001/05/30 07:41:03 peter Exp $
* Bytecode utility functions
*
* Copyright (C) 2001 Peter Johnson
static immval im_static;
unsigned char bytes_static[16];
-/* FIXME: converting int to EA, but we don't know addrsize yet?
- currently assumes BITS setting.. probably better to always do calculations
- in 32 bits in case BITS 16 is going to be overridden later in parsing. */
-
effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val)
{
if(!ptr)
ptr = &eff_static;
- ptr->addrsize = 0;
ptr->segment = 0;
- if(mode_bits == 32) {
- ptr->offset = int_val;
- ptr->len = 4;
- ptr->modrm = 0x05; /* Mod=00 R/M=disp32, Reg=0 */
- ptr->need_modrm = 1;
- ptr->need_sib = 0;
- } else if(mode_bits == 16) {
- ptr->offset = int_val & 0xFFFF;
+ ptr->valid_modrm = 0;
+ ptr->need_modrm = 1;
+ ptr->valid_sib = 0;
+ ptr->need_sib = 0;
+
+ ptr->disp = int_val;
+
+ if((int_val & 0xFF) == int_val)
+ ptr->len = 1;
+ else if((int_val & 0xFFFF) == int_val)
ptr->len = 2;
- ptr->modrm = 0x06; /* Mod=00 R/M=disp16, Reg=0 */
- ptr->need_modrm = 1;
- ptr->need_sib = 0;
- } else
- return (effaddr *)NULL;
+ else
+ ptr->len = 4;
return ptr;
}
ptr = &eff_static;
ptr->len = 0;
- ptr->addrsize = 0;
ptr->segment = 0;
ptr->modrm = 0xC0 | (reg & 0x07); /* Mod=11, R/M=Reg, Reg=0 */
+ ptr->valid_modrm = 1;
ptr->need_modrm = 1;
+ ptr->valid_sib = 0;
ptr->need_sib = 0;
return ptr;
if(!ptr)
ptr = &eff_static;
- ptr->offset = im_ptr->val;
+ ptr->disp = im_ptr->val;
if(im_ptr->len > im_len)
Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word");
ptr->len = im_len;
- ptr->addrsize = 0;
ptr->segment = 0;
+ ptr->valid_modrm = 0;
ptr->need_modrm = 0;
+ ptr->valid_sib = 0;
ptr->need_sib = 0;
return ptr;
if(!ptr)
return;
- if(ptr->segment != 0) {
- Error(ERR_INVALID_EA, (char *)NULL);
- return;
- }
+ if(ptr->segment != 0)
+ Warning(WARN_MULT_SEG_OVERRIDE, (char *)NULL);
ptr->segment = segment;
}
-void SetEAAddressSize(effaddr *ptr, unsigned char addrsize, unsigned char len)
+void SetEALen(effaddr *ptr, unsigned char len)
+{
+ if(!ptr)
+ return;
+
+ /* Currently don't warn if length truncated, as this is called only from
+ * an explicit override, where we expect the user knows what they're doing.
+ */
+
+ ptr->len = len;
+}
+
+void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize)
+{
+ if(!bc)
+ return;
+
+ bc->data.insn.opersize = opersize;
+}
+
+void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize)
{
+ if(!bc)
+ return;
+
+ bc->data.insn.addrsize = addrsize;
+}
+
+void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix)
+{
+ if(!bc)
+ return;
+
+ if(bc->data.insn.lockrep_pre != 0)
+ Warning(WARN_MULT_LOCKREP_PREFIX, (char *)NULL);
+
+ bc->data.insn.lockrep_pre = prefix;
}
void BuildBC_Insn(bytecode *bc,
bc->data.insn.ea.modrm |= (spare << 3) & 0x38; /* plug in provided bits */
} else {
bc->data.insn.ea.len = 0;
- bc->data.insn.ea.addrsize = 0;
bc->data.insn.ea.segment = 0;
bc->data.insn.ea.need_modrm = 0;
bc->data.insn.ea.need_sib = 0;
if(im_ptr) {
bc->data.insn.imm = *im_ptr;
+ bc->data.insn.imm.f_rel = im_rel;
+ bc->data.insn.imm.f_sign = im_sign;
+ bc->data.insn.imm.f_len = im_len;
} else {
bc->data.insn.imm.len = 0;
+ bc->data.insn.imm.f_rel = 0;
+ bc->data.insn.imm.f_sign = 0;
+ bc->data.insn.imm.f_len = 0;
}
- bc->data.insn.f_rel_imm = im_rel;
- bc->data.insn.f_sign_imm = im_sign;
- bc->data.insn.f_len_imm = im_len;
bc->data.insn.opcode[0] = op0;
bc->data.insn.opcode[1] = op1;
bc->data.insn.opcode[2] = op2;
bc->data.insn.opcode_len = opcode_len;
+ bc->data.insn.addrsize = 0;
bc->data.insn.opersize = opersize;
bc->len = 0;
case BC_INSN:
printf("_Instruction_\n");
printf("Effective Address:\n");
- printf(" Offset=%lx Len=%u\n", bc->data.insn.ea.offset,
- (unsigned int)bc->data.insn.ea.len);
- printf(" AddrSize=%u SegmentOv=%2x\n",
- (unsigned int)bc->data.insn.ea.addrsize,
+ printf(" Disp=%lx Len=%u SegmentOv=%2x\n", bc->data.insn.ea.disp,
+ (unsigned int)bc->data.insn.ea.len,
(unsigned int)bc->data.insn.ea.segment);
- printf(" ModRM=%2x NeedRM=%u SIB=%2x NeedSIB=%u\n",
+ printf(" ModRM=%2x ValidRM=%u NeedRM=%u\n",
(unsigned int)bc->data.insn.ea.modrm,
- (unsigned int)bc->data.insn.ea.need_modrm,
+ (unsigned int)bc->data.insn.ea.valid_modrm,
+ (unsigned int)bc->data.insn.ea.need_modrm);
+ printf(" SIB=%2x ValidSIB=%u NeedSIB=%u\n",
(unsigned int)bc->data.insn.ea.sib,
+ (unsigned int)bc->data.insn.ea.valid_sib,
(unsigned int)bc->data.insn.ea.need_sib);
printf("Immediate/Relative Value:\n");
- printf(" Val=%lx Len=%u, IsRel=%u\n", bc->data.insn.imm.val,
+ printf(" Val=%lx\n", bc->data.insn.imm.val);
+ printf(" Len=%u, IsRel=%u, IsNeg=%u\n",
(unsigned int)bc->data.insn.imm.len,
- (unsigned int)bc->data.insn.imm.isrel);
+ (unsigned int)bc->data.insn.imm.isrel,
+ (unsigned int)bc->data.insn.imm.isneg);
printf(" FLen=%u, FRel=%u, FSign=%u\n",
- (unsigned int)bc->data.insn.f_len_imm,
- (unsigned int)bc->data.insn.f_rel_imm,
- (unsigned int)bc->data.insn.f_sign_imm);
+ (unsigned int)bc->data.insn.imm.f_len,
+ (unsigned int)bc->data.insn.imm.f_rel,
+ (unsigned int)bc->data.insn.imm.f_sign);
printf("Opcode: %2x %2x OpLen=%u\n",
(unsigned int)bc->data.insn.opcode[0],
(unsigned int)bc->data.insn.opcode[1],
-/* $Id: bytecode.h,v 1.6 2001/05/30 07:07:16 peter Exp $
+/* $Id: bytecode.h,v 1.7 2001/05/30 07:41:03 peter Exp $
* Bytecode utility functions header file
*
* Copyright (C) 2001 Peter Johnson
#define _BYTECODE_H_
typedef struct effaddr_s {
- unsigned long offset;
- unsigned char len; /* length of offset (in bytes), 0 if none */
- unsigned char addrsize; /* 16 or 32, 0 indicates no override */
+ unsigned long disp; /* address displacement */
+ unsigned char len; /* length of disp (in bytes), 0 if none */
+
unsigned char segment; /* segment override, 0 if none */
+
unsigned char modrm;
+ unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
+
unsigned char sib;
+ unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
} effaddr;
typedef struct immval_s {
unsigned long val;
+
unsigned char len; /* length of val (in bytes), 0 if none */
unsigned char isrel;
unsigned char isneg; /* the value has been explicitly negated */
+
+ unsigned char f_len; /* final imm length */
+ unsigned char f_rel; /* 1 if final imm should be rel */
+ unsigned char f_sign; /* 1 if final imm should be signed */
} immval;
typedef struct bytecode_s {
effaddr ea; /* effective address */
immval imm; /* immediate or relative value */
- unsigned char f_len_imm; /* final imm length */
- unsigned char f_rel_imm; /* 1 if final imm should be rel */
- unsigned char f_sign_imm; /* 1 if final imm should be signed */
unsigned char opcode[3]; /* opcode */
unsigned char opcode_len;
+ unsigned char addrsize; /* 0 indicates no override */
unsigned char opersize; /* 0 indicates no override */
unsigned char lockrep_pre; /* 0 indicates no prefix */
} insn;
immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
void SetEASegment(effaddr *ptr, unsigned char segment);
-void SetEAAddressSize(effaddr *ptr, unsigned char addrsize, unsigned char len);
+void SetEALen(effaddr *ptr, unsigned char len);
+
+void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
+void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
+void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
void BuildBC_Insn(bytecode *bc,
unsigned char opersize,
-/* $Id: bytecode.c,v 1.7 2001/05/30 07:07:16 peter Exp $
+/* $Id: bytecode.c,v 1.8 2001/05/30 07:41:03 peter Exp $
* Bytecode utility functions
*
* Copyright (C) 2001 Peter Johnson
static immval im_static;
unsigned char bytes_static[16];
-/* FIXME: converting int to EA, but we don't know addrsize yet?
- currently assumes BITS setting.. probably better to always do calculations
- in 32 bits in case BITS 16 is going to be overridden later in parsing. */
-
effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val)
{
if(!ptr)
ptr = &eff_static;
- ptr->addrsize = 0;
ptr->segment = 0;
- if(mode_bits == 32) {
- ptr->offset = int_val;
- ptr->len = 4;
- ptr->modrm = 0x05; /* Mod=00 R/M=disp32, Reg=0 */
- ptr->need_modrm = 1;
- ptr->need_sib = 0;
- } else if(mode_bits == 16) {
- ptr->offset = int_val & 0xFFFF;
+ ptr->valid_modrm = 0;
+ ptr->need_modrm = 1;
+ ptr->valid_sib = 0;
+ ptr->need_sib = 0;
+
+ ptr->disp = int_val;
+
+ if((int_val & 0xFF) == int_val)
+ ptr->len = 1;
+ else if((int_val & 0xFFFF) == int_val)
ptr->len = 2;
- ptr->modrm = 0x06; /* Mod=00 R/M=disp16, Reg=0 */
- ptr->need_modrm = 1;
- ptr->need_sib = 0;
- } else
- return (effaddr *)NULL;
+ else
+ ptr->len = 4;
return ptr;
}
ptr = &eff_static;
ptr->len = 0;
- ptr->addrsize = 0;
ptr->segment = 0;
ptr->modrm = 0xC0 | (reg & 0x07); /* Mod=11, R/M=Reg, Reg=0 */
+ ptr->valid_modrm = 1;
ptr->need_modrm = 1;
+ ptr->valid_sib = 0;
ptr->need_sib = 0;
return ptr;
if(!ptr)
ptr = &eff_static;
- ptr->offset = im_ptr->val;
+ ptr->disp = im_ptr->val;
if(im_ptr->len > im_len)
Warning(WARN_VALUE_EXCEEDS_BOUNDS, (char *)NULL, "word");
ptr->len = im_len;
- ptr->addrsize = 0;
ptr->segment = 0;
+ ptr->valid_modrm = 0;
ptr->need_modrm = 0;
+ ptr->valid_sib = 0;
ptr->need_sib = 0;
return ptr;
if(!ptr)
return;
- if(ptr->segment != 0) {
- Error(ERR_INVALID_EA, (char *)NULL);
- return;
- }
+ if(ptr->segment != 0)
+ Warning(WARN_MULT_SEG_OVERRIDE, (char *)NULL);
ptr->segment = segment;
}
-void SetEAAddressSize(effaddr *ptr, unsigned char addrsize, unsigned char len)
+void SetEALen(effaddr *ptr, unsigned char len)
+{
+ if(!ptr)
+ return;
+
+ /* Currently don't warn if length truncated, as this is called only from
+ * an explicit override, where we expect the user knows what they're doing.
+ */
+
+ ptr->len = len;
+}
+
+void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize)
+{
+ if(!bc)
+ return;
+
+ bc->data.insn.opersize = opersize;
+}
+
+void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize)
{
+ if(!bc)
+ return;
+
+ bc->data.insn.addrsize = addrsize;
+}
+
+void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix)
+{
+ if(!bc)
+ return;
+
+ if(bc->data.insn.lockrep_pre != 0)
+ Warning(WARN_MULT_LOCKREP_PREFIX, (char *)NULL);
+
+ bc->data.insn.lockrep_pre = prefix;
}
void BuildBC_Insn(bytecode *bc,
bc->data.insn.ea.modrm |= (spare << 3) & 0x38; /* plug in provided bits */
} else {
bc->data.insn.ea.len = 0;
- bc->data.insn.ea.addrsize = 0;
bc->data.insn.ea.segment = 0;
bc->data.insn.ea.need_modrm = 0;
bc->data.insn.ea.need_sib = 0;
if(im_ptr) {
bc->data.insn.imm = *im_ptr;
+ bc->data.insn.imm.f_rel = im_rel;
+ bc->data.insn.imm.f_sign = im_sign;
+ bc->data.insn.imm.f_len = im_len;
} else {
bc->data.insn.imm.len = 0;
+ bc->data.insn.imm.f_rel = 0;
+ bc->data.insn.imm.f_sign = 0;
+ bc->data.insn.imm.f_len = 0;
}
- bc->data.insn.f_rel_imm = im_rel;
- bc->data.insn.f_sign_imm = im_sign;
- bc->data.insn.f_len_imm = im_len;
bc->data.insn.opcode[0] = op0;
bc->data.insn.opcode[1] = op1;
bc->data.insn.opcode[2] = op2;
bc->data.insn.opcode_len = opcode_len;
+ bc->data.insn.addrsize = 0;
bc->data.insn.opersize = opersize;
bc->len = 0;
case BC_INSN:
printf("_Instruction_\n");
printf("Effective Address:\n");
- printf(" Offset=%lx Len=%u\n", bc->data.insn.ea.offset,
- (unsigned int)bc->data.insn.ea.len);
- printf(" AddrSize=%u SegmentOv=%2x\n",
- (unsigned int)bc->data.insn.ea.addrsize,
+ printf(" Disp=%lx Len=%u SegmentOv=%2x\n", bc->data.insn.ea.disp,
+ (unsigned int)bc->data.insn.ea.len,
(unsigned int)bc->data.insn.ea.segment);
- printf(" ModRM=%2x NeedRM=%u SIB=%2x NeedSIB=%u\n",
+ printf(" ModRM=%2x ValidRM=%u NeedRM=%u\n",
(unsigned int)bc->data.insn.ea.modrm,
- (unsigned int)bc->data.insn.ea.need_modrm,
+ (unsigned int)bc->data.insn.ea.valid_modrm,
+ (unsigned int)bc->data.insn.ea.need_modrm);
+ printf(" SIB=%2x ValidSIB=%u NeedSIB=%u\n",
(unsigned int)bc->data.insn.ea.sib,
+ (unsigned int)bc->data.insn.ea.valid_sib,
(unsigned int)bc->data.insn.ea.need_sib);
printf("Immediate/Relative Value:\n");
- printf(" Val=%lx Len=%u, IsRel=%u\n", bc->data.insn.imm.val,
+ printf(" Val=%lx\n", bc->data.insn.imm.val);
+ printf(" Len=%u, IsRel=%u, IsNeg=%u\n",
(unsigned int)bc->data.insn.imm.len,
- (unsigned int)bc->data.insn.imm.isrel);
+ (unsigned int)bc->data.insn.imm.isrel,
+ (unsigned int)bc->data.insn.imm.isneg);
printf(" FLen=%u, FRel=%u, FSign=%u\n",
- (unsigned int)bc->data.insn.f_len_imm,
- (unsigned int)bc->data.insn.f_rel_imm,
- (unsigned int)bc->data.insn.f_sign_imm);
+ (unsigned int)bc->data.insn.imm.f_len,
+ (unsigned int)bc->data.insn.imm.f_rel,
+ (unsigned int)bc->data.insn.imm.f_sign);
printf("Opcode: %2x %2x OpLen=%u\n",
(unsigned int)bc->data.insn.opcode[0],
(unsigned int)bc->data.insn.opcode[1],
-/* $Id: bytecode.h,v 1.6 2001/05/30 07:07:16 peter Exp $
+/* $Id: bytecode.h,v 1.7 2001/05/30 07:41:03 peter Exp $
* Bytecode utility functions header file
*
* Copyright (C) 2001 Peter Johnson
#define _BYTECODE_H_
typedef struct effaddr_s {
- unsigned long offset;
- unsigned char len; /* length of offset (in bytes), 0 if none */
- unsigned char addrsize; /* 16 or 32, 0 indicates no override */
+ unsigned long disp; /* address displacement */
+ unsigned char len; /* length of disp (in bytes), 0 if none */
+
unsigned char segment; /* segment override, 0 if none */
+
unsigned char modrm;
+ unsigned char valid_modrm; /* 1 if Mod/RM byte currently valid, 0 if not */
unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */
+
unsigned char sib;
+ unsigned char valid_sib; /* 1 if SIB byte currently valid, 0 if not */
unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */
} effaddr;
typedef struct immval_s {
unsigned long val;
+
unsigned char len; /* length of val (in bytes), 0 if none */
unsigned char isrel;
unsigned char isneg; /* the value has been explicitly negated */
+
+ unsigned char f_len; /* final imm length */
+ unsigned char f_rel; /* 1 if final imm should be rel */
+ unsigned char f_sign; /* 1 if final imm should be signed */
} immval;
typedef struct bytecode_s {
effaddr ea; /* effective address */
immval imm; /* immediate or relative value */
- unsigned char f_len_imm; /* final imm length */
- unsigned char f_rel_imm; /* 1 if final imm should be rel */
- unsigned char f_sign_imm; /* 1 if final imm should be signed */
unsigned char opcode[3]; /* opcode */
unsigned char opcode_len;
+ unsigned char addrsize; /* 0 indicates no override */
unsigned char opersize; /* 0 indicates no override */
unsigned char lockrep_pre; /* 0 indicates no prefix */
} insn;
immval *ConvertIntToImm(immval *ptr, unsigned long int_val);
void SetEASegment(effaddr *ptr, unsigned char segment);
-void SetEAAddressSize(effaddr *ptr, unsigned char addrsize, unsigned char len);
+void SetEALen(effaddr *ptr, unsigned char len);
+
+void SetInsnOperSizeOverride(bytecode *bc, unsigned char opersize);
+void SetInsnAddrSizeOverride(bytecode *bc, unsigned char addrsize);
+void SetInsnLockRepPrefix(bytecode *bc, unsigned char prefix);
void BuildBC_Insn(bytecode *bc,
unsigned char opersize,