summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-10-17 23:29:11 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-10-17 23:29:11 -0700
commit0a20bcfaf17fc78e97fc609bb60087529df79eea (patch)
treeccc218633a953026eb81849bbc81193626bb6465
parent93c7aa23028c53e6ebf43861d2c778fb01fa895a (diff)
downloadnasm-0a20bcfaf17fc78e97fc609bb60087529df79eea.tar.gz
assemble: for OUT_REL*ADR, the "size" argument is not really size...
For OUT_REL*ADR, the "size" argument is actually the offset inside the instruction; that is in fact why we encode the real size in the instruction itself. Thus, emit the offsets properly using this mechanism when generating relative EAs. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--assemble.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/assemble.c b/assemble.c
index aade9d4c..dfc83a05 100644
--- a/assemble.c
+++ b/assemble.c
@@ -1811,14 +1811,17 @@ static void gencode(int32_t segment, int64_t offset, int bits,
warn_overflow(ea_data.bytes, opx);
s += ea_data.bytes;
if (ea_data.rip) {
- data -= insn_end - (offset+ea_data.bytes);
- type = OUT_REL4ADR;
+ out(offset, segment, &data,
+ OUT_REL4ADR, insn_end - offset,
+ ins->oprs[(c >> 3) & 7].segment,
+ ins->oprs[(c >> 3) & 7].wrt);
} else {
type = OUT_ADDRESS;
+ out(offset, segment, &data,
+ OUT_ADDRESS, ea_data.bytes,
+ ins->oprs[(c >> 3) & 7].segment,
+ ins->oprs[(c >> 3) & 7].wrt);
}
- out(offset, segment, &data, type, ea_data.bytes,
- ins->oprs[(c >> 3) & 7].segment,
- ins->oprs[(c >> 3) & 7].wrt);
break;
}
offset += s;