summaryrefslogtreecommitdiff
path: root/disasm.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-01-02 12:19:41 -0800
committerH. Peter Anvin <hpa@zytor.com>2008-01-02 12:20:38 -0800
commit08367e22315b0ba1011fa42987468fa3630c166f (patch)
tree9f4605b0cb4e1ca0b99e39bfb1008b3dfb043458 /disasm.c
parentb8b1a61d107b9eab93912ab79835c09c302c4066 (diff)
downloadnasm-08367e22315b0ba1011fa42987468fa3630c166f.tar.gz
disasm: relative operands are signed, not unsigned
Relative operands are signed, not unsigned; record them as such and then apply proper truncation after offset addition.
Diffstat (limited to 'disasm.c')
-rw-r--r--disasm.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/disasm.c b/disasm.c
index e7e508eb..e6b97ad7 100644
--- a/disasm.c
+++ b/disasm.c
@@ -350,7 +350,7 @@ static uint8_t *do_ea(uint8_t *data, int modrm, int asize,
break;
case 2:
op->segment |= SEG_DISP32;
- op->offset = getu32(data);
+ op->offset = gets32(data);
data += 4;
break;
}
@@ -557,11 +557,11 @@ static int matches(const struct itemplate *t, uint8_t *data,
case4(064):
opx->segment |= SEG_RELATIVE;
if (osize == 16) {
- opx->offset = getu16(data);
+ opx->offset = gets16(data);
data += 2;
opx->segment &= ~(SEG_32BIT|SEG_64BIT);
} else if (osize == 32) {
- opx->offset = getu32(data);
+ opx->offset = gets32(data);
data += 4;
opx->segment &= ~SEG_64BIT;
opx->segment |= SEG_32BIT;
@@ -574,7 +574,7 @@ static int matches(const struct itemplate *t, uint8_t *data,
break;
case4(070):
- opx->offset = getu32(data);
+ opx->offset = gets32(data);
data += 4;
opx->segment |= SEG_32BIT | SEG_RELATIVE;
break;
@@ -1096,6 +1096,9 @@ int32_t disasm(uint8_t *data, char *output, int outbufsize, int segsize,
*/
if (!(o->segment & (SEG_32BIT|SEG_64BIT)))
offs &= 0xffff;
+ else if (segsize != 64)
+ offs &= 0xffffffff;
+
/*
* add sync marker, if autosync is on
*/