summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2011-04-30 10:11:00 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-29 16:30:54 +0100
commit2fa288d0599369012465056a06c6ea09ce2a1134 (patch)
treea031abf60a3a34c1ed1bdc48fa5ce3059a8aac89
parente30e85c727c9796eaaf18475809f06927a2ba846 (diff)
downloaddev86-2fa288d0599369012465056a06c6ea09ce2a1134.tar.gz
Check for incorrect REP/REPNE prefix usev0.16.20
-rw-r--r--as/asm/each.asm39
-rw-r--r--as/assemble.c10
-rw-r--r--as/errors.c3
-rw-r--r--as/errors.h3
4 files changed, 55 insertions, 0 deletions
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" */