diff options
author | H. Peter Anvin <hpa@zytor.com> | 2008-01-02 12:19:41 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2008-01-02 12:20:38 -0800 |
commit | 08367e22315b0ba1011fa42987468fa3630c166f (patch) | |
tree | 9f4605b0cb4e1ca0b99e39bfb1008b3dfb043458 /disasm.c | |
parent | b8b1a61d107b9eab93912ab79835c09c302c4066 (diff) | |
download | nasm-08367e22315b0ba1011fa42987468fa3630c166f.tar.gz nasm-08367e22315b0ba1011fa42987468fa3630c166f.tar.bz2 nasm-08367e22315b0ba1011fa42987468fa3630c166f.zip |
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.c | 11 |
1 files changed, 7 insertions, 4 deletions
@@ -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 */ |