Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!cmcl2!brl-adm!umd5!mimsy!oddjob!hao!noao!mcdsun!fnf From: fnf@mcdsun.UUCP (Fred Fish) Newsgroups: comp.lang.c Subject: Re: Types Message-ID: <384@mcdsun.UUCP> Date: Tue, 6-Oct-87 20:32:01 EDT Article-I.D.: mcdsun.384 Posted: Tue Oct 6 20:32:01 1987 Date-Received: Sat, 10-Oct-87 19:24:27 EDT References: <7264@brl-adm.ARPA> <734@sdchema.sdchem.UUCP> <293@osupyr.UUCP> <366@mcdsun.UUCP> <899@mcgill-vision.UUCP> Reply-To: fnf@mcdsun.UUCP (Fred Fish) Organization: Motorola Microcomputer Division Lines: 63 In article <899@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: [stuff deleted... fnf] >> Sigh, guess we are going to have to go into the gory details. [stuff deleted... fnf] >> The assembler assumes all jumps are near jumps > >But that is exactly what it mustn't do. I would expect the assembler >to produce a near jump for the first one, since it knows that one is >near. For the other two, it must produce far jumps, or at least >reserve enough space for a far jump. Then the linker can either cop >out and use a far jump when the offset would have fit in 16 bits or it >can replace it with a near jump. If it replaces it, it either has to >fill 32 bits with some sort of no-op or else it has to move stuff. If >you choose to shrink things, the assembler will have to tell the loader >about the first jump as well (the offset will need changing). Gee, its been a while since this topic came around the first time, so lots of people will probably be totally in the dark about the original issues. Speaking strictly for those that remember the discussion, let me reiterate the major points: 1. The assembler *does not* do any relocation, computation of offsets, or whatever you want to call it. When it sees a symbol, either local or global, it just stuffs it into the symbol table to be passed on to the linker and creates a relocation entry for the current offset. I'm really puzzled by people's persistent belief that the assembler should do anything else (other than conditioning from current released implementations for most CISC processors). 2. The assembler has to emit either a "near" jump for a "far" jump bit pattern in the object code (I guess it could emit a third "insert appropriate jump instruction here" code, but why bother). If you default to "near" jumps, you have the linker fix up all the jumps that are really "far" jumps to be "far" jumps. If you default to "far" jumps, you have the linker fix up all the jumps that are really "near" jumps to be "near" jumps. In either case, you either grow or shrink the code as appropriate, in the linker. What could be easier? In either case, you end up with exactly the same executable object code. No nops, no "non-optimal" jumps, the *same* *optimal* *code*. 3. Now the only choice is to decide which default you want. For my implementation, it was obvious that near jumps were the correct default. For another situation, the reverse might be true. I don't claim that either is somehow theoretically "better". (Someone else might care to claim so though, don't let me stop you... :-) >UNIX currently has something reminiscent of this: the assembler chooses >branch instructions in near/far variants and fixes the instruction type >at assemble time, pessimizing for undefined symbols. The loader merely >fills in the offsets, even if a shorter instruction sequence would have >been possible had it been known that the target was as close as it is. Don't let existing sub-optimal solutions cloud your vision. -Fred -- # Fred Fish hao!noao!mcdsun!fnf (602) 438-3614 # Motorola Computer Division, 2900 S. Diablo Way, Tempe, Az 85282 USA