[comp.unix.sysv386] crufty memcmp on 386

gls@cbnewsh.att.com (Col. G. L. Sicherman) (11/13/90)

There is a problem with the memcmp routine on my 6386WGS running Vr3.2.
The ordering it returns is not transitive, or even antisymmetric.  In
other words, it can tell you that x < y and y < x, or that x < y < z < x.

I do not know whether the formal specifications for memcmp require that
it produces a lineal ordering, but obviously it should.  A nonlineal
memcmp cannot be used for sorting and searching.

The 386-specific code does this:

	jz	zeroexit
	lahf		// load low byte of flags to high byte of AX
	cwtl		// convert word to longword with sign extension

There are two problems with this.  One is that if EAX contains zero and
all the flag bits are 0, it will return 0 instead of positive.  This
never seems to happen; apparently the unused bit 1 is always set to 1.

The other is that it effectively returns the sign flag as the sign of
the result.  Even PDP-11 programmers know better than that!  There are
two ways to give a consistent ordering on a 386:

	1. Use unsigned byte comparison.  This amounts to replacing
	   the CWTL by a 9-bit right rotate, to put the carry flag
	   into the sign position.  There is probably a faster way;
	   I don't have a 386 manual.  Like the method above, this
	   assumes that bit 1 of the flags is set -- otherwise you
	   could get zero.

	2. Use consistent signed byte comparison.  This means testing
	   for SF=OF.  The simplest way to do it is with a JGE, but
	   again there may well be a faster way.

Is anybody working on a fix for the code and (if necessary) the formal
specs for memcmp()?
-- 
Col. G. L. Sicherman
gls@odyssey.att.COM