Path: csiph.com!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news.iecc.com!.POSTED.news.iecc.com!nerds-end From: drb@ihatespam.msu.edu (Dennis Boone) Newsgroups: comp.compilers Subject: Re: PR1ME C compiler sources and pointer formats Date: Mon, 30 Sep 2019 22:10:13 -0500 Organization: Compilers Central Lines: 92 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <19-10-001@comp.compilers> References: <19-09-003@comp.compilers> <19-09-004@comp.compilers> <19-09-016@comp.compilers> <19-09-019@comp.compilers> Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="42666"; mail-complaints-to="abuse@iecc.com" Keywords: C, architecture, history Posted-Date: 01 Oct 2019 10:38:43 EDT X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:2371 > I don't know where you saw the description of the register set. I > suspect it was only describing the "general purpose registers" > associated with IX-mode (which I knew as I*-mode). The 48 bit pointer > registers are not part of that set. And, what I was describing > previously was the way the C compiler worked in V-mode. Reading the > documentation on the C compiler for IX-mode. It is clear that they > added a whole new way of dealing with 32 bit pointers using the > general purpose registers. Ignoring floating point stuff, the registers are all 16- or 32-bit. The 48 bit pointers are strictly memory-based. I mode is a general register mode. It doesn't do much of anything to hide segmentation. It does include register-relative addressing, that is, putting pointers into general registers. IX mode is a small extension to I mode, which adds some additional manipulation of pointers in registers, and some support for C character manipulation. Again, doesn't do much of anything to hide segmentation. > So, what follows is what I remember of the V-mode segmented address > space (with some guesses as to how they probably tweaked it for > IX-mode to make it appear more linear). There were 4 pointer > registers in V-mode. PB -- a pointer to the instruction space. LB -- > a pointer to "static" memory. SB -- a pointer to the "stack frame". > XB -- a pointer for general use. If I recall correctly, only the XB > was actually modifiable by normal code; done with the EAXB > instruction, calculate effective address (including doing > indirections) and store it in the XB register. The PB, LB, and SB > registers were only changed by the PCL (procedure call) instruction > (and it's corresponding return). Each of these registers had the two > bits I mentioned previously (although, I forgot the ring bits which > separated them), a ring number 0, 1, 2, or 3 (the OS ran in ring 0 and > user code ran in ring 3, the DBMS used ring 1 or 2 if I recall > correctly, but the other ring was unused), a segment number, a > half-word (16 bit offset), and a bit offset (that was only used by the > hardware at the character (8 bit) level). I suppose the base registers are "pointer registers" in the strict sense, but 3/4 of them have fixed purposes. You can directly alter the contents of LB and XB via the EALB and EAXB instructions. The obvious way to alter PB is to use a PCL instruction. The only one left is SB, which you can modify by using the RSAV and RRST instructions to save registers and restore them. > Calls to the OS or DBMS were done through the standard PCL mechanism > which would change which ring you were running in (increasing your > priority), but every segment also had a ring number (as well as every > pointer) had a ring number associated with it and the values were > ORed, so that you got the lowest priority access. Thus, if you fudged > a pointer and you called into the OS, the OS would see your pointer > was in a lower priority space and use only the access rights that > space had to that address. Code could also lower the priority of a > pointer itself, by setting the ring bits, and I believe if you stored > a pointer, the hardware stored the ring bits in the saved pointer to > be the weak access it was using. So, even if your pointer got copied > into a ring 0 memory location, it would remain a ring 3 pointer if it > originally came from user space. Entrance to the OS is through the PCL instruction and the gate mechanism. The microcode and/or the OS perform ring selection and weakening as needed to ensure security. Storing a pointer does not cause any change in it. > The hardware supported at least 3 faults related to pointers. Access > violation, the pointer was accessing a segment in a way it didn't have > rights to, with roughly the same 3 mode bits read, write, and execute > for each ring. Pointer fault, the fault bit in the pointer was set. > and page fault, the pointer pointed to a page that wasn't currently > mapped in. I believe there was also a segment fault for segments that > did not exist. A pointer fault can occur for several reasons: the fault bit being set, pointing into an invalid location, etc. Page faults are part of the virtual memory mechanism, and are not reflected to the user via a condition the way a segmentation or pointer fault (or others). > So, my guess is that IX mode did roughly that, putting the XB at the > start of the linear address space for C programs and making the > instructions which used the GPR registers as pointers, do the > appropriate bit twiddling in hardware but basing the resulting address > off the XB. Alternately, the instructions using the GPR registers as > pointers could have used "absolute addressing" with no base register, > letting the pointers deal with the segments (and their ring > restrictions) as required. The rings and segments would have still > been there but the code would have had the 29 bits to play with and > probably treated all accesses as if it were from ring 3. I haven't spent as much time with I mode as with V, but the usual idiom is to move XB around as needed. De