Xref: utzoo comp.sys.ibm.pc:21970 comp.sys.intel:588
Path: utzoo!utgpu!watmath!mks!egisin
From: egisin@mks.UUCP (Eric Gisin)
Newsgroups: comp.sys.ibm.pc,comp.sys.intel
Subject: correct code for pointer subtraction
Summary: attention compiler hacks
Message-ID: <597@mks.UUCP>
Date: 9 Dec 88 00:27:15 GMT
Organization: Mortice Kern Systems, Waterloo, Ont.
Lines: 33

How come I can't find a compiler that generates correct
code for pointer subtraction in C on 8086s?
Neither Turbo, Microsoft, or Watcom do it right.
Here's an example:

struct six {
	int i[3];
};

int diff(struct six far* p, struct six far* q) {
  	return p - q;
}

main(void) {
	struct six s[1];
	printf("%d\n", diff(s+10000, s));	/* 10000 */
	printf("%d\n", diff(s, s+100));		/* -100 */
}

All of the compilers I tried computed a 16 bit difference,
then sign extended it before dividing.
This does not work if the pointers differ by more than 32K.
The proper method is to propagate the borrow flag into the high
order 16 bits, like this:

	mov	ax,WORD PTR [bp+4]	;p
	sub	ax,WORD PTR [bp+8]	;q
	sbb	dx,dx			; NOT cwd !!!
	mov	cx,6
	idiv	cx

Now I have to manually grep through a thousand lines of code
looking for any pointer subtractions to fix a bug.