From: Йордан Г. <col...@gm...> - 2012-07-01 07:14:18
|
The current version of Nasm never generates mod 0 rm 5 bytes to address memory or code, thus it can only be linked with /LARGEADDRESSAWARE:NO by the Microsoft linkers. Additionally you can't specify a base larger than 0x7FFFFFFF. My patch fixes that. Also I make the proposition that in addition to "db", "dw", "dd", "dq", etc. keywords we add "dp" (as in define pointer). It is to be the same size as the program's BITS mode. In 64-bit mode it would behave as dq, in 32-bit as dd, and in 16-bit as dw. Signed-off-by: Jordan Gigov <col...@gm...> diff --git a/assemble.c b/assemble.c index 1a1e2df..751bd31 100644 --- a/assemble.c +++ b/assemble.c @@ -662,8 +662,8 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp, if (instruction->opcode == I_DB || instruction->opcode == I_DW || instruction->opcode == I_DD || instruction->opcode == I_DQ || - instruction->opcode == I_DT || instruction->opcode == I_DO || - instruction->opcode == I_DY) { + instruction->opcode == I_DP || instruction->opcode == I_DT || + instruction->opcode == I_DO || instruction->opcode == I_DY) { extop *e; int32_t isize, osize, wsize; @@ -2311,11 +2311,10 @@ static enum ea_type process_ea(operand *input, ea *output, int bits, } if (bits == 64 && (~input->type & IP_REL)) { - output->sib_present = true; - output->sib = GEN_SIB(0, 4, 5); + output->sib_present = false; output->bytes = 4; - output->modrm = GEN_MODRM(0, rfield, 4); - output->rip = false; + output->modrm = GEN_MODRM(0, rfield, 5); + output->rip = true; } else { output->sib_present = false; output->bytes = (addrbits != 16 ? 4 : 2); diff --git a/insns.dat b/insns.dat index 1f277a9..e4eb740 100644 --- a/insns.dat +++ b/insns.dat @@ -52,6 +52,7 @@ DB ignore ignore ignore DW ignore ignore ignore DD ignore ignore ignore DQ ignore ignore ignore +DP ignore ignore ignore DT ignore ignore ignore DO ignore ignore ignore DY ignore ignore ignore @@ -59,6 +60,7 @@ RESB imm [ resb] 8086 RESW ignore ignore ignore RESD ignore ignore ignore RESQ ignore ignore ignore +RESP ignore ignore ignore REST ignore ignore ignore RESO ignore ignore ignore RESY ignore ignore ignore diff --git a/nasm.c b/nasm.c index 63e73e7..2ef802b 100644 --- a/nasm.c +++ b/nasm.c @@ -1673,6 +1673,17 @@ static void assemble_file(char *fname, StrList **depend_ptr) typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD; break; + case I_RESP: + if(globalbits == 64) + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_QWORD; + else if(globalbits == 32) + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_DWORD; + else + typeinfo = + TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_WORD; + break; case I_REST: typeinfo = TYS_ELEMENTS(output_ins.oprs[0].offset) | TY_TBYTE; @@ -1700,6 +1711,14 @@ static void assemble_file(char *fname, StrList **depend_ptr) case I_DQ: typeinfo |= TY_QWORD; break; + case I_DP: + if(globalbits == 64) + typeinfo |= TY_QWORD; + else if(globalbits == 32) + typeinfo |= TY_DWORD; + else + typeinfo |= TY_WORD; + break; case I_DT: typeinfo |= TY_TBYTE; break; diff --git a/nasmlib.c b/nasmlib.c index 2367ff3..65729a9 100644 --- a/nasmlib.c +++ b/nasmlib.c @@ -784,6 +784,13 @@ int idata_bytes(int opcode) return 4; case I_DQ: return 8; + case I_DP: + if(globalbits == 64) + return 8; + else if(globalbits == 32) + return 4; + else + return 2; case I_DT: return 10; case I_DO: diff --git a/parser.c b/parser.c index aa2df24..d2d1d2c 100644 --- a/parser.c +++ b/parser.c @@ -355,8 +355,9 @@ restart_parse: 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_INCBIN) { + result->opcode == I_DP || result->opcode == I_DT || + result->opcode == I_DO || result->opcode == I_DY || + result->opcode == I_INCBIN) { extop *eop, **tail = &result->eops, **fixptr; int oper_num = 0; int32_t sign; @@ -364,7 +365,7 @@ restart_parse: result->eops_float = false; /* - * Begin to read the DB/DW/DD/DQ/DT/DO/INCBIN operands. + * Begin to read the DB/DW/DD/DQ/DP/DT/DO/INCBIN operands. */ while (1) { i = stdscan(NULL, &tokval); |