home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   alt.os.development      Operating system development chatter      4,255 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 3,071 of 4,255   
   James Harris to wolfgang kern   
   Re: The EA jump immediately after enabli   
   12 Feb 22 11:08:39   
   
   From: james.harris.1@gmail.com   
      
   On 10/02/2022 22:33, wolfgang kern wrote:   
   > On 10/02/2022 15:47, James Harris wrote:   
      
   I think I may have come up with a clearer insight into what happens at   
   each step of enabling Pmode - and it's very little! See below for details.   
      
   > ...   
   >> It seems a bit of a conundrum and leads to the obvious question:   
   >> exactly what differences are there between instruction decoding in   
   >> real mode and in PM16 (the mode immediately after setting CR0 bit 0?   
   >   
   >> As I say, this is all largely academic but if you happen to know the   
   >> answer without doing any research do say as the details look interesting.   
   >   
   > 1. this EB 00 after write CR0 were never required, at least not by me.   
      
    From what I've found recently it looks as though it would be rare for   
   anyone to need that jump. (Though it or something like it is still right   
   to include to cover the unusual cases.)   
      
   > 2. setting PE does nothing on its own, the CPU remain in real mode until   
   >     the far jump which changes interpretation from segment to descriptor.   
   >     and its a 16:16 code without prefix   
      
   I am not sure that's right, Wolfgang. I am beginning to think that once   
   PE is set the processor will be in 16-bit Protected Mode (PM16); in that   
   mode the encoding of instructions will be identical to RM; and the main   
   differences will be when loading segment registers. There may also be   
   some differences when /using/ segment registers but see below.   
      
   I have been looking at the 80286 manuals to find out more about PM16. It   
   turns out that it has the same addressing limitations as the 8086, i.e.   
      
      BP/BX + SI/DI + displacement   
      
   and apparently the same encoding.   
      
   (Ref. 80286 and 80287 programmer's manual 1987 section 2.3.3 and table 2-1)   
      
   If PM16 has the same encoding of instructions and of addressing modes as   
   RM then then the question arises as to what that jmp to flush the decode   
   queue is for?   
      
   After setting PE there will be zero or more of the following bytes   
   already decoded. (The number will vary according to the processor, its   
   caching, and the dynamic flow of prior instructions.) Those encodings   
   and meanings will be the same in PM16 as they were in RM for most   
   instructions so the question is Where does it matter?   
      
   I can think of two potential cases:   
      
   1. /Loading/ a segment register.   
      
   When a segment register is loaded in PM16 the processor gets a memory   
   descriptor from a descriptor table much as it does in PM32. The   
   descriptor includes a base and a limit. AFIACS this is the first   
   relevant difference from RM. A segment register reloaded in PM16 would   
   not necessarily refer to the same address as it would in RM. Consider a   
   sequence such as   
      
      lmsw  ax         ;Enter protected mode   
      mov   ds, bx   
      
   In that, if the MOV has already been decoded then segment register DS   
   would be loaded with the value of BX but if the MOV had not been decoded   
   then DS would be loaded with the descriptor which BX selects.   
      
   2. Using a segment register.   
      
   The second potential scenario is /using/ a segment register. Consider   
      
      lmsw  ax         ;Enter protected mode   
      mov   ax, [val]   
      
   The [val] reference would use DS so what is the code likely to do?   
      
   It is possible that a processor would trigger an interrupt to indicate   
   an exception because DS was not valid for PM. It could even lock up.   
      
   But there is another possibility. The 80286 and later CPUs could have   
   been designed to use the internal PM-type descriptors at all times, even   
   when running in RM. They would essentially need to make sure that when a   
   segment register is loaded in Real Mode that the base address, limit and   
   flags are set appropriately:   
      
      base = seg << 4   
      limit = 0xffff   
      flags = don't check anything   
      
   The hardware engineers could have taken either approach but I suspect   
   the latter. That's for three reasons. First, Pmode operation can subsume   
   that in Rmode allowing the difference to be only when segment registers   
   are loaded. Second, they did exactly that with the IVT. And third, they   
   would probably have had to do that for the code segment. I say that   
   because the CPU has to continue to retrieve bytes of code after the   
   switch to PM16 and as we've seen from Intel examples, such code could   
   continue for an arbitrary number of bytes before loading a new selector   
   into CS. So accesses relative to CS would /have/ to continue to use the   
   old interpretation of CS until the code reloaded it. It would be natural   
   to apply the same rules to DS and other segment registers.   
      
   IOW, after enabling Pmode the JMP instruction was required to ensure   
   that subsequent loads of segment registers used the Pmode interpretation   
   rather than the Rmode one ... and possibly nothing else.   
      
   Of course, it's still right to include an immediate jump for portability   
   and this is all speculation but ISTM that it does give a simple and   
   consistent model of the likely state of the processor between enabling   
   Pmode and reloading segment registers: Whether in Rmode or Pmode the PE   
   bit primarily determines what effect loading a segment register has.   
      
   In summary:   
      
      mov cr0, eax   ;Enter Pmode   
      ... nothing changed in the CPU other than the PE bit   
      ... instructions using same encoding & addressing as in Rmode   
      mov ax, 8  ;Operates normally   
      jmp $ + 2   
      ... still nothing else changed in the architectural state of the   
      ... CPU except that we have ensured that the following segment   
      ... register access will be interpreted correctly for Pmode   
      mov ds, ax   
      ... DS now has base, limit and protections as loaded from GDT   
      
   That's it. Feel free to disagree.   
      
   But if I am right then it's amazing how little changes in the CPU   
   between each step.   
      
      
      
   --   
   James Harris   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca