From e9bd95fd96187e3013c2de88af995c32573ab9cf Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Mon, 21 May 2001 20:17:51 +0000 Subject: [PATCH] Added conversion from immediate value to effective address. Used for enter instruction (which takes two immediate values). To facilitate this change, changed meaning of "len" in bytecode structure to be only the length of the offset (from being 1+length, the 1 being for the Mod/RM byte), and added a need_modrm flag similar to the need_sib flag in functionality. svn path=/trunk/yasm/; revision=22 --- include/bytecode.h | 10 ++++++---- libyasm/bytecode.c | 32 +++++++++++++++++++++++++++----- libyasm/bytecode.h | 10 ++++++---- src/bytecode.c | 32 +++++++++++++++++++++++++++----- src/bytecode.h | 10 ++++++---- 5 files changed, 72 insertions(+), 22 deletions(-) diff --git a/include/bytecode.h b/include/bytecode.h index 452b967d..aa5b0d39 100644 --- a/include/bytecode.h +++ b/include/bytecode.h @@ -1,4 +1,4 @@ -/* $Id: bytecode.h,v 1.3 2001/05/21 19:32:51 mu Exp $ +/* $Id: bytecode.h,v 1.4 2001/05/21 20:17:51 peter Exp $ * Bytecode utility functions header file * * Copyright (C) 2001 Peter Johnson @@ -24,12 +24,13 @@ typedef struct effaddr_s { unsigned long offset; - unsigned char len; /* length of offset + 1 (for RM) (in bytes) */ - unsigned char addrsize; /* 8, 16, or 32, 0 indicates no override */ + unsigned char len; /* length of offset (in bytes), 0 if none */ + unsigned char addrsize; /* 16 or 32, 0 indicates no override */ unsigned char segment; /* segment override, 0 if none */ unsigned char modrm; + unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */ unsigned char sib; - unsigned char need_sib; + unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */ } effaddr; typedef struct immval_s { @@ -77,6 +78,7 @@ typedef struct bytecode_s { effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val); effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg); +effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len); immval *ConvertIntToImm(immval *ptr, unsigned long int_val); diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index 52ac2ac9..1ddbc915 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -1,4 +1,4 @@ -/* $Id: bytecode.c,v 1.3 2001/05/21 19:32:51 mu Exp $ +/* $Id: bytecode.c,v 1.4 2001/05/21 20:17:51 peter Exp $ * Bytecode utility functions * * Copyright (C) 2001 Peter Johnson @@ -22,6 +22,7 @@ #include #include "globals.h" #include "bytecode.h" +#include "errwarn.h" static effaddr eff_static; static immval im_static; @@ -41,13 +42,15 @@ effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val) if(mode_bits == 32) { ptr->offset = int_val; - ptr->len = 5; + 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->len = 3; + 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; @@ -60,10 +63,28 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg) if(!ptr) ptr = &eff_static; - ptr->len = 1; + ptr->len = 0; ptr->addrsize = 0; ptr->segment = 0; ptr->modrm = 0xC0 | (reg & 0x07); /* Mod=11, R/M=Reg, Reg=0 */ + ptr->need_modrm = 1; + ptr->need_sib = 0; + + return ptr; +} + +effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len) +{ + if(!ptr) + ptr = &eff_static; + + ptr->offset = 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->need_modrm = 0; ptr->need_sib = 0; return ptr; @@ -160,8 +181,9 @@ void DebugPrintBC(bytecode *bc) printf(" AddrSize=%u SegmentOv=%2x\n", (unsigned int)bc->data.insn.ea.addrsize, (unsigned int)bc->data.insn.ea.segment); - printf(" ModRM=%2x SIB=%2x NeedSIB=%u\n", + printf(" ModRM=%2x NeedRM=%u SIB=%2x NeedSIB=%u\n", (unsigned int)bc->data.insn.ea.modrm, + (unsigned int)bc->data.insn.ea.need_modrm, (unsigned int)bc->data.insn.ea.sib, (unsigned int)bc->data.insn.ea.need_sib); printf("Immediate/Relative Value:\n"); diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index 452b967d..aa5b0d39 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -1,4 +1,4 @@ -/* $Id: bytecode.h,v 1.3 2001/05/21 19:32:51 mu Exp $ +/* $Id: bytecode.h,v 1.4 2001/05/21 20:17:51 peter Exp $ * Bytecode utility functions header file * * Copyright (C) 2001 Peter Johnson @@ -24,12 +24,13 @@ typedef struct effaddr_s { unsigned long offset; - unsigned char len; /* length of offset + 1 (for RM) (in bytes) */ - unsigned char addrsize; /* 8, 16, or 32, 0 indicates no override */ + unsigned char len; /* length of offset (in bytes), 0 if none */ + unsigned char addrsize; /* 16 or 32, 0 indicates no override */ unsigned char segment; /* segment override, 0 if none */ unsigned char modrm; + unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */ unsigned char sib; - unsigned char need_sib; + unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */ } effaddr; typedef struct immval_s { @@ -77,6 +78,7 @@ typedef struct bytecode_s { effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val); effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg); +effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len); immval *ConvertIntToImm(immval *ptr, unsigned long int_val); diff --git a/src/bytecode.c b/src/bytecode.c index 52ac2ac9..1ddbc915 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -1,4 +1,4 @@ -/* $Id: bytecode.c,v 1.3 2001/05/21 19:32:51 mu Exp $ +/* $Id: bytecode.c,v 1.4 2001/05/21 20:17:51 peter Exp $ * Bytecode utility functions * * Copyright (C) 2001 Peter Johnson @@ -22,6 +22,7 @@ #include #include "globals.h" #include "bytecode.h" +#include "errwarn.h" static effaddr eff_static; static immval im_static; @@ -41,13 +42,15 @@ effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val) if(mode_bits == 32) { ptr->offset = int_val; - ptr->len = 5; + 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->len = 3; + 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; @@ -60,10 +63,28 @@ effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg) if(!ptr) ptr = &eff_static; - ptr->len = 1; + ptr->len = 0; ptr->addrsize = 0; ptr->segment = 0; ptr->modrm = 0xC0 | (reg & 0x07); /* Mod=11, R/M=Reg, Reg=0 */ + ptr->need_modrm = 1; + ptr->need_sib = 0; + + return ptr; +} + +effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len) +{ + if(!ptr) + ptr = &eff_static; + + ptr->offset = 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->need_modrm = 0; ptr->need_sib = 0; return ptr; @@ -160,8 +181,9 @@ void DebugPrintBC(bytecode *bc) printf(" AddrSize=%u SegmentOv=%2x\n", (unsigned int)bc->data.insn.ea.addrsize, (unsigned int)bc->data.insn.ea.segment); - printf(" ModRM=%2x SIB=%2x NeedSIB=%u\n", + printf(" ModRM=%2x NeedRM=%u SIB=%2x NeedSIB=%u\n", (unsigned int)bc->data.insn.ea.modrm, + (unsigned int)bc->data.insn.ea.need_modrm, (unsigned int)bc->data.insn.ea.sib, (unsigned int)bc->data.insn.ea.need_sib); printf("Immediate/Relative Value:\n"); diff --git a/src/bytecode.h b/src/bytecode.h index 452b967d..aa5b0d39 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -1,4 +1,4 @@ -/* $Id: bytecode.h,v 1.3 2001/05/21 19:32:51 mu Exp $ +/* $Id: bytecode.h,v 1.4 2001/05/21 20:17:51 peter Exp $ * Bytecode utility functions header file * * Copyright (C) 2001 Peter Johnson @@ -24,12 +24,13 @@ typedef struct effaddr_s { unsigned long offset; - unsigned char len; /* length of offset + 1 (for RM) (in bytes) */ - unsigned char addrsize; /* 8, 16, or 32, 0 indicates no override */ + unsigned char len; /* length of offset (in bytes), 0 if none */ + unsigned char addrsize; /* 16 or 32, 0 indicates no override */ unsigned char segment; /* segment override, 0 if none */ unsigned char modrm; + unsigned char need_modrm; /* 1 if Mod/RM byte needed, 0 if not */ unsigned char sib; - unsigned char need_sib; + unsigned char need_sib; /* 1 if SIB byte needed, 0 if not */ } effaddr; typedef struct immval_s { @@ -77,6 +78,7 @@ typedef struct bytecode_s { effaddr *ConvertIntToEA(effaddr *ptr, unsigned long int_val); effaddr *ConvertRegToEA(effaddr *ptr, unsigned long reg); +effaddr *ConvertImmToEA(effaddr *ptr, immval *im_ptr, unsigned char im_len); immval *ConvertIntToImm(immval *ptr, unsigned long int_val); -- 2.40.0