From 2fa288d0599369012465056a06c6ea09ce2a1134 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 30 Apr 2011 10:11:00 +0200 Subject: Check for incorrect REP/REPNE prefix use --- as/asm/each.asm | 39 +++++++++++++++++++++++++++++++++++++++ as/assemble.c | 10 ++++++++++ as/errors.c | 3 +++ as/errors.h | 3 +++ 4 files changed, 55 insertions(+) (limited to 'as') diff --git a/as/asm/each.asm b/as/asm/each.asm index 2145489..371b20e 100644 --- a/as/asm/each.asm +++ b/as/asm/each.asm @@ -104,10 +104,49 @@ rcr [esi*4],1 rol [esi*4],1 ror [esi*4],1 rep +ins +rep +outs +rep +movs +rep +cmps +rep +stos +rep +scas +repe +ins +repe +outs +repe +movs +repe +cmps repe +stos +repe +scas +repz +ins +repz +outs +repz +movs repz +cmps +repz +stos +repz +scas repne +scas +repne +cmps +repnz +scas repnz +cmps ret retf sahf diff --git a/as/assemble.c b/as/assemble.c index 5af954e..10349a1 100644 --- a/as/assemble.c +++ b/as/assemble.c @@ -199,6 +199,7 @@ PUBLIC void assemble() PRIVATE void asline() { register struct sym_s *symptr; + opcode_t prevop; postb = popflags = pcrflag = #ifdef I80386 @@ -317,9 +318,18 @@ PRIVATE void asline() mcount = 1; } } + prevop = opcode; opcode = symptr->value_reg_or_op.op.opcode; #ifdef I80386 needcpu((page==0 && ((opcode&0xF0) == 0x60||(opcode&0xF6)==0xC0))?1:0); + /* We handle "rep[ne]" refix as separate instruction; check if it's valid */ + if (prevop == 0xF2 && (opcode&0xF6) != 0xA6) /* REPNE CMPS/SCAS */ + error (REPNE_STRING); + if (prevop == 0xF3 && !((opcode&0xFC) == 0x6C || /* REP INS/OUTS */ + (opcode&0xFC) == 0xA4 || /* REP MOVS/CMPS */ + (opcode&0xFC) == 0xAC || /* REP SCAS/LODS */ + (opcode&0xFE) == 0xAA)) /* REP STOS */ + error (REP_STRING); #endif routine = rout_table[symptr->value_reg_or_op.op.routine]; getsym(); diff --git a/as/errors.c b/as/errors.c index 4a78a7f..de9b507 100644 --- a/as/errors.c +++ b/as/errors.c @@ -103,6 +103,9 @@ PUBLIC char JUNK_AFTER_OPERANDS[] = "junk after operands"; PUBLIC char ALREADY[] = "already defined"; PUBLIC char UNSTABLE_LABEL[] = "label moved in last pass add -O?"; +PUBLIC char REPNE_STRING[] = "CMPS or SCAS expected"; +PUBLIC char REP_STRING[] = "string instruction expected"; + /* Warnings. */ PUBLIC char CPUCLASH[] = "instruction illegal for current cpu"; PUBLIC char SHORTB[] = "short branch would do"; diff --git a/as/errors.h b/as/errors.h index ac26b6d..451ac41 100644 --- a/as/errors.h +++ b/as/errors.h @@ -103,6 +103,9 @@ EXTERN char JUNK_AFTER_OPERANDS[]; /* "junk after operands" */ EXTERN char ALREADY[]; /* "already defined" */ EXTERN char UNSTABLE_LABEL[]; /* "label moved in last pass add -O?" */ +EXTERN char REPNE_STRING[]; /* "CMPS or SCAS expected" */ +EXTERN char REP_STRING[]; /* "string instruction expected" */ + /* Warnings. */ EXTERN char CPUCLASH[]; /* "instruction illegal for current cpu" */ EXTERN char SHORTB[]; /* "short branch would do" */ -- cgit v1.2.1