From 17799b40c049df74a5d563aae7667e618fb46953 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 21 May 2002 03:31:21 +0000 Subject: [PATCH] JMP instructions use the operand size prefix, not the address size prefix, to determine the size of the jump target. --- CHANGES | 12 ++++++++++++ assemble.c | 20 ++++++++++++-------- disasm.c | 9 ++++++--- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/CHANGES b/CHANGES index 039a86d..a3ee2a6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,15 @@ +0.98.33 +------- +* New __NASM_PATCHLEVEL__ and __NASM_VERSION_ID__ standard macros to + round out the version-query macros. version.pl now understands + X.YYplWW or X.YY.ZZplWW as a version number, equivalent to + X.YY.ZZ.WW (or X.YY.0.WW, as appropriate). +* New keyword "strict" to disable the optimization of a specific + operand. +* Fix the handing of size overrides with JMP instructions + (instructions such as "jmp dword foo".) + + 0.98.32 ------- diff --git a/assemble.c b/assemble.c index 1e8b9b9..b87b104 100644 --- a/assemble.c +++ b/assemble.c @@ -28,7 +28,7 @@ * \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 - * assembly mode or the address-size override on the operand + * assembly mode or the operand-size override on the operand * \70, \71, \72 - a long relative operand, from operand 0, 1 or 2 * \1ab - a ModRM, calculated on EA in operand a, with the spare * field the register value of operand b. @@ -601,8 +601,11 @@ static long calcsize (long segment, long offset, int bits, case 060: case 061: case 062: length += 2; break; case 064: case 065: case 066: - length += ((ins->oprs[c-064].addr_size ? - ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); break; + if ( ins->oprs[c-064].type & (BITS16|BITS32) ) + length += (ins->oprs[c-064].type & BITS16) ? 2 : 4; + else + length += (bits == 16) ? 2 : 4; + break; case 070: case 071: case 072: length += 4; break; case 0130: case 0131: case 0132: @@ -849,14 +852,15 @@ static void gencode (long segment, long offset, int bits, break; case 064: case 065: case 066: - size = ((ins->oprs[c-064].addr_size ? - ins->oprs[c-064].addr_size : bits) == 16 ? 2 : 4); + if ( ins->oprs[c-064].type & (BITS16|BITS32) ) + size = (ins->oprs[c-064].type & BITS16) ? 2 : 4; + else + size = (bits == 16) ? 2 : 4; if (ins->oprs[c-064].segment != segment) { + long reltype = (size == 2 ? OUT_REL2ADR : OUT_REL4ADR); data = ins->oprs[c-064].offset; - size = (bits == 16 ? OUT_REL2ADR : OUT_REL4ADR); - out (offset, segment, &data, size+insn_end-offset, + out (offset, segment, &data, reltype+insn_end-offset, ins->oprs[c-064].segment, ins->oprs[c-064].wrt); - size = (bits == 16 ? 2 : 4); } else { data = ins->oprs[c-064].offset - insn_end; out (offset, segment, &data, diff --git a/disasm.c b/disasm.c index 9184686..acc6e3f 100644 --- a/disasm.c +++ b/disasm.c @@ -360,15 +360,18 @@ static int matches (struct itemplate *t, unsigned char *data, int asize, if (c >= 064 && c <= 066) { ins->oprs[c-064].offset = *data++; ins->oprs[c-064].offset |= (*data++ << 8); - if (asize == 32) { + if (osize == 32) { ins->oprs[c-064].offset |= (((long) *data++) << 16); ins->oprs[c-064].offset |= (((long) *data++) << 24); ins->oprs[c-064].segment |= SEG_32BIT; } else ins->oprs[c-064].segment &= ~SEG_32BIT; ins->oprs[c-064].segment |= SEG_RELATIVE; - if (segsize != asize) - ins->oprs[c-064].addr_size = asize; + if (segsize != osize) { + ins->oprs[c-064].type = + (ins->oprs[c-064].type & NON_SIZE) + | ((osize == 16) ? BITS16 : BITS32); + } } if (c >= 070 && c <= 072) { ins->oprs[c-070].offset = *data++; -- 2.7.4