Xref: utzoo comp.sys.ibm.pc:22300 comp.sys.intel:607 Path: utzoo!utgpu!attcan!uunet!lll-winken!lll-tis!ames!oliveb!pyramid!prls!philabs!ttidca!quad1!few From: few@quad1.quad.com (Frank Whaley) Newsgroups: comp.sys.ibm.pc,comp.sys.intel Subject: Re: correct code for pointer subtraction Keywords: huge far Message-ID: <1626@quad1.quad.com> Date: 11 Dec 88 09:00:37 GMT References: <597@mks.UUCP> Reply-To: few@quad1.quad.com (Frank Whaley) Organization: Quadratron Systems, Westlake Village, CA Lines: 37 In article <597@mks.UUCP> egisin@mks.UUCP (Eric Gisin) writes: >How come I can't find a compiler that generates correct >code for pointer subtraction in C on 8086s? >struct six { > int i[3]; >}; >int diff(struct six far* p, struct six far* q) { > return p - q; >} Yet another subtlety of segmented architectures... Use "huge" instead of "far" -- and return a "long" instead of an "int". Both "far" and "huge" imply 32-bit values, but since most programs work with <64K objects, the optimization has been taken towards 16-bit arithmetic (offset only). Note that using "huge model" does not make pointers "huge" -- they must be individually specified (in Turbo C at least). I prefer Lattice's method of handling this via a command line switch, rather than by requiring source changes. >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 Actually, the correct method is to convert both pointers to 20-bit absolute addresses, and then perform the arithmetic. Most compilers provide subroutines for this, as it's a bit much for inline code. -- Frank Whaley Senior Development Engineer Quadratron Systems Incorporated few@quad1.quad.com Water separates the people of the world; Wine unites them.