386 / 486 bugs and strange instructions

by Grzegorz Mazur

Last update: 2000-09-18

Revision history:
20000918 - minor corrections
961119 - construction started.

The bug is present in all 386DX chips and in early revisions of 386SX family models. If the POPAD instruction is followed by instruction using 32-bit indexed addressing mode, EAX register content is not properly restored by POPA/POPAD instruction. The bug is very deterministic, so it can be used to differentiate between Intel/AMD 386 and other similar processors.
32 bit MULtiply bug
The bug occurs in early 386 chips with 32-bit bus (later called 386DX). While performing multiplication with particular data values, the result is incorrect. The bug is probably indeterministic, but frequent - that means that to detect it one should perform the multiplication several times (64K suggested), and check the result.
The suggested test sequence is:
IDIV bug
Integer divide bug is present at least in 386 DX, Intel/AMD 486 chips and IBM 386/486SLC CPUs. For some values of arguments that shall cause divide overflow (exception 0), the overflow is not signalled. The "faulty" values are listed below:
Variant Dividend range (hex) Divisor (hex)
16 by 8 8002..807f 7f
32 by 16 bit 80000002..80007fff 7fff
64 by 32 bit 8000000000000002..800000007fffffff 7fffffff
Intel dealt with the problem by redefining the IDIV instruction. The current Intel manuals say that the dividend must be a 64-/32-/16-bit sign-extended value of 32-/16/8-bit argument, otherwise the results are undefined. Nice shot!
(Big Thanks to Jim Cook for rediscovering the bug...)
The bug occurs in 386DX B1 step (and probably earlier) chips. While performing REP INSB with initial value of CX = 1, the CX register is not decremented to zero.
Present in early 386 (486?). REP MOVS instruction prefixed with ASIZE prefix is executed improperly if the following instruction doesn't have ASIZE prefix. Workaround: place ASIZE NOP after REP MOVS.
On some (which?) early 486 revisions while performing 16-bit mode STOSB instruction, whole EDI register is incremented instead of DI.
IBTS and XBTS instructions
These instructions were introduced in early 386 and removed soon. They should be present in A and B0 stepping of 386. On later steppings they cause undefined opcode exception.
CMPXCHG instruction in early 486
In early 486 CMPXCHG opcodes were 0FA6 and 0FA7, identical to the opcodes of IBTS and XBTS in early 386. Later the opcodes were changed to 0FB0 and 0FB1.

The End
Copyright 1996-2000 by Grzegorz Mazur