correct code for pointer subtraction

Pete Alleman pja at ralph.UUCP
Mon Jan 9 04:03:12 AEST 1989


In article <2254 at iscuva.ISCS.COM> carlp at iscuva.ISCS.COM (Carl Paukstis) writes:
>In article <22905 at watmath.waterloo.edu> rwwetmore at grand.waterloo.edu (Ross Wetmore) writes:
>>In article <2245 at iscuva.ISCS.COM> carlp at iscuva (Carl Paukstis) writes:
>>>Eric Gisin at Mortice Kern Systems writes:
>>>>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.
>>>>
>>>>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.
>                                                          ^^^ BYTES!
>>>
>>>(NOTE CRITICAL POINT FOR ERIC'S COMPLAINT:  the difference between s and
>>>s+10000 is 60,000 bytes - easily less that the 64K segment limit)
>
>>  The 64K segment limit has little to do with it. The 16 bit architecture
>>ie 16 bit _int_ is the determining factor.

But on a 16 bit machine you have the 16 bit result AND A CARRY FLAG.  That
gives the full 17 bit representation needed for the signed result!

>Which point was that?  What DOES happen in other 16-bit-int environments?
>Would somebody care to run Eric's example and let me know the outcome? 

I tried this simple program on a PDP-11 running K&R's V7 compiler:

	int a[20000];
	main ()
	{
		printf ("%d\n", &a[20000] - &a[0]);
	}

Sure enough, it gets the right answer! (20000)

Here is an example of the proper code on a 16 bit machine:
	_main:
		jsr	r5,csv
		mov	$-61700+_a,r1
		sub	$_a,r1
		bic	r0,r0
		sbc	r0
		div	$2,r0
		mov	r0,(sp)
		mov	$L4,-(sp)
		jsr	pc,*$_printf
		tst	(sp)+
		jmp	cret

The problem is NOT a limitation of the processor!  Some compilers just
generate WRONG CODE.  (I'm glad such stupidity is usually restricted to
IBM FECES and MESSY-DOS)

-- 
Pete Alleman
	ralph!pja or
	digitran!pja



More information about the Comp.lang.c mailing list