summaryrefslogtreecommitdiff
path: root/assemble.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2002-05-27 23:19:35 +0000
committerH. Peter Anvin <hpa@zytor.com>2002-05-27 23:19:35 +0000
commit3ba467795a364e7a95ba04a99ffc6ed2c2d2959d (patch)
tree5c6f2b487bd891215e266c07066deb593c6feb8b /assemble.c
parent0b23240481eafc8a1a2120a36b7a349ae7d5bbc2 (diff)
downloadnasm-3ba467795a364e7a95ba04a99ffc6ed2c2d2959d.tar.gz
Deal with another case of address/operand size confusion, BR 560873
Diffstat (limited to 'assemble.c')
-rw-r--r--assemble.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/assemble.c b/assemble.c
index b87b1040..9f557595 100644
--- a/assemble.c
+++ b/assemble.c
@@ -22,9 +22,11 @@
* \24, \25, \26 - an unsigned byte immediate operand, from operand 0, 1 or 2
* \30, \31, \32 - a word immediate operand, from operand 0, 1 or 2
* \34, \35, \36 - select between \3[012] and \4[012] depending on 16/32 bit
- * assembly mode or the address-size override on the operand
+ * assembly mode or the operand-size override on the operand
* \37 - a word constant, from the _segment_ part of operand 0
* \40, \41, \42 - a long immediate operand, from operand 0, 1 or 2
+ * \44, \45, \46 - select between \3[012] and \4[012] depending on 16/32 bit
+ * assembly mode or the address-size override on the operand
* \50, \51, \52 - a byte relative operand, from operand 0, 1 or 2
* \60, \61, \62 - a word relative operand, from operand 0, 1 or 2
* \64, \65, \66 - select between \6[012] and \7[012] depending on 16/32 bit
@@ -590,12 +592,18 @@ static long calcsize (long segment, long offset, int bits,
case 030: case 031: case 032:
length += 2; break;
case 034: case 035: case 036:
- length += ((ins->oprs[c-034].addr_size ?
- ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4); break;
+ if ( ins->oprs[c-034].type & (BITS16|BITS32) )
+ length += (ins->oprs[c-034].type & BITS16) ? 2 : 4;
+ else
+ length += (bits == 16) ? 2 : 4;
+ break;
case 037:
length += 2; break;
case 040: case 041: case 042:
length += 4; break;
+ case 044: case 045: case 046:
+ length += ((ins->oprs[c-044].addr_size ?
+ ins->oprs[c-044].addr_size : bits) == 16 ? 2 : 4); break;
case 050: case 051: case 052:
length++; break;
case 060: case 061: case 062:
@@ -799,9 +807,11 @@ static void gencode (long segment, long offset, int bits,
break;
case 034: case 035: case 036:
+ if ( ins->oprs[c-034].type & (BITS16|BITS32) )
+ size = (ins->oprs[c-034].type & BITS16) ? 2 : 4;
+ else
+ size = (bits == 16) ? 2 : 4;
data = ins->oprs[c-034].offset;
- size = ((ins->oprs[c-034].addr_size ?
- ins->oprs[c-034].addr_size : bits) == 16 ? 2 : 4);
if (size==2 && (data < -65536L || data > 65535L))
errfunc (ERR_WARNING, "word value exceeds bounds");
out (offset, segment, &data, OUT_ADDRESS+size,
@@ -827,6 +837,17 @@ static void gencode (long segment, long offset, int bits,
offset += 4;
break;
+ case 044: case 045: case 046:
+ data = ins->oprs[c-044].offset;
+ size = ((ins->oprs[c-044].addr_size ?
+ ins->oprs[c-044].addr_size : bits) == 16 ? 2 : 4);
+ if (size==2 && (data < -65536L || data > 65535L))
+ errfunc (ERR_WARNING, "word value exceeds bounds");
+ out (offset, segment, &data, OUT_ADDRESS+size,
+ ins->oprs[c-044].segment, ins->oprs[c-044].wrt);
+ offset += size;
+ break;
+
case 050: case 051: case 052:
if (ins->oprs[c-050].segment != segment)
errfunc (ERR_NONFATAL, "short relative jump outside segment");