summaryrefslogtreecommitdiff
path: root/asm/parser.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2017-05-01 20:28:29 -0700
committerH. Peter Anvin <hpa@zytor.com>2017-05-01 21:13:15 -0700
commit3e458a89d8c985527313305b55d5725cf382e862 (patch)
tree3b1ec93afc10e5e389ce1c74cb32f28a743ac52a /asm/parser.c
parent5810c594c9eeed4d809b29c9e073af76dfcd3249 (diff)
downloadnasm-3e458a89d8c985527313305b55d5725cf382e862.tar.gz
a) Fix handling of DZ/ZWORD; b) don't crash on TIMES JMP
a) Fix a number of missing instances of DZ and ZWORD. b) NASM would crash if TIMES was used on an instruction which varies in size, e.g. JMP. Fix this by moving the handling of TIMES at a higher level, so we generate the instruction "de novo" for each iteration. The exception is INCBIN, so we can avoid reading the included file over and over. c) When using the RESx instructions, just fold TIMES into the reserved space size; there is absolutely no point to iterate over it. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'asm/parser.c')
-rw-r--r--asm/parser.c47
1 files changed, 8 insertions, 39 deletions
diff --git a/asm/parser.c b/asm/parser.c
index d1e82ed0..d701d7fd 100644
--- a/asm/parser.c
+++ b/asm/parser.c
@@ -444,6 +444,9 @@ restart_parse:
stdscan_set(buffer);
i = stdscan(NULL, &tokval);
+ nasm_static_assert(P_none == 0);
+ memset(result->prefixes, P_none, sizeof(result->prefixes));
+ result->times = 1; /* No TIMES either yet */
result->label = NULL; /* Assume no label */
result->eops = NULL; /* must do this, whatever happens */
result->operands = 0; /* must initialize this */
@@ -491,10 +494,6 @@ restart_parse:
if (i == TOKEN_EOS)
goto fail;
- nasm_static_assert(P_none == 0);
- memset(result->prefixes, P_none, sizeof(result->prefixes));
- result->times = 1L;
-
while (i == TOKEN_PREFIX ||
(i == TOKEN_REG && IS_SREG(tokval.t_integer))) {
first = false;
@@ -581,11 +580,7 @@ restart_parse:
} else
critical = (pass == 2 ? 2 : 0);
- if (result->opcode == I_DB || result->opcode == I_DW ||
- result->opcode == I_DD || result->opcode == I_DQ ||
- result->opcode == I_DT || result->opcode == I_DO ||
- result->opcode == I_DY || result->opcode == I_DZ ||
- result->opcode == I_INCBIN) {
+ if (opcode_is_db(result->opcode) || result->opcode == I_INCBIN) {
extop *eop, **tail = &result->eops, **fixptr;
int oper_num = 0;
int32_t sign;
@@ -1133,37 +1128,11 @@ is_expression:
/*
* Transform RESW, RESD, RESQ, REST, RESO, RESY, RESZ into RESB.
*/
- switch (result->opcode) {
- case I_RESW:
- result->opcode = I_RESB;
- result->oprs[0].offset *= 2;
- break;
- case I_RESD:
+ if (opcode_is_resb(result->opcode)) {
+ result->oprs[0].offset *= resv_bytes(result->opcode);
+ result->oprs[0].offset *= result->times;
+ result->times = 1;
result->opcode = I_RESB;
- result->oprs[0].offset *= 4;
- break;
- case I_RESQ:
- result->opcode = I_RESB;
- result->oprs[0].offset *= 8;
- break;
- case I_REST:
- result->opcode = I_RESB;
- result->oprs[0].offset *= 10;
- break;
- case I_RESO:
- result->opcode = I_RESB;
- result->oprs[0].offset *= 16;
- break;
- case I_RESY:
- result->opcode = I_RESB;
- result->oprs[0].offset *= 32;
- break;
- case I_RESZ:
- result->opcode = I_RESB;
- result->oprs[0].offset *= 64;
- break;
- default:
- break;
}
return result;