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,102 of 4,255   
   James Harris to wolfgang kern   
   Re: The EA jump immediately after enabli   
   21 Feb 22 18:02:26   
   
   From: james.harris.1@gmail.com   
      
   On 21/02/2022 14:30, wolfgang kern wrote:   
   > On 21/02/2022 13:13, James Harris wrote:   
   >   
   >>>>> BUT how about   
   >>>>> PM32:   
   >>>>> 8B 44 24 fc     mov eax.[esp-04]  ;SP or ESP depending on seg-size ?   
   >>>>> RM:   
   >>>>> 67 8B 44 24 fc  mov ax,[esp-04]   ;could have an UnReal flat big stack   
   >   
   >>>> How do you interpret those?   
   >>> my disassembler do this for me.   
   >> :)  I was asking what you thought they meant (in the context of   
   >> different descriptor settings).   
   >   
   >> I've been looking in to this a bit more and will have a go at it. See   
   >> if you think I've got it right or not.   
   >   
   > can't give you an A here ...   
   > both of my and your example instructions use SS by default.   
      
   You are right about using SS. Since the earlier post I've found in the   
   Intel manual under Default Segment Selection Rules the text for uses of   
   SS and it mentions ESP as well as EBP: "Any memory reference which uses   
   the ESP or EBP register as a base register." I'd missed off ESP. I will   
   correct my comments, below, though please don't get diverted by that   
   because the selection of base register is a side issue compared with the   
   significance(s) of the D/B bit.   
      
   I should say that IME assemblers have no directives for RM or PM32 but   
   only for "16-bit" and "32-bit" and AISI they are correct in that because   
   for both of the 16-bit modes (RM and PM16) the instruction encodings are   
   identical.   
      
   Therefore, AISI your second example (which you labelled "RM") cannot   
   really be RM as it refers to ESP so I presume you mean PM16 (which uses   
   16-bit encodings but can refer to 32-bit registers).   
      
   BTW, to be clear, you referred to /my/ examples but I just copied yours   
   so there are only two examples, not four.   
      
   >   
   >> Your first example:   
   >> PM32:   
   >>    8B 44 24 fc  mov eax.[esp-04]  ;SP or ESP depending on seg-size ?   
   >> AIUI:   
   >> * that will NOT use the SS segment's 'B' bit (which selects SP or ESP   
   >> but does so only for /implicit/ references to the stack)   
      
   I stand by that part of the assessment (until told otherwise!). The B   
   bit is only used for implicit stack operations and is ignored for   
   explicit ones.   
      
   >   
   >> * it will use the CS segment's D bit being set to 1 in two ways:   
   >>    1) it will have adsiz as 32-bit so recognising ESP rather than SP   
   >>    2) it will have opsiz as 32-bit so recognising EAX rather than AX   
      
   I stand by that, too.   
      
   >   
   >> * the accessible range will depend on DS.limit, not SS.limit   
   >>   
   >> * it will access ESP relative to DS.base, not relative to SS.base -   
   >> which could be a source of significant confusion if they don't match.   
   >   
   > My SS use a PM16 data-descriptor and my DS a Flat PM32 one.   
   > No confusion detected :)   
      
   Agreed. If MOV EAX,[ESP - 4] uses ESP as a base register then it /will/   
   use SS.limit and SS.base - although for that instruction the CPU will   
   still ignore SS.B. Agreed?   
      
   >   
   >> Your second example:   
   >> RM:   
   >>    67 8B 44 24 fc  mov ax,[esp-04]   ;could have an UnReal flat big   
   stack   
   >   
   >> * again, won't use anything about the SS segment   
   >> * will use CS.D=0 to recognise AX   
   >   
   > yeah, RM uses 16 bit for AX by default, but 67 allow SIB (uses SS)   
      
   Agreed.   
      
   >   
   >> * will use CS.D=0 and adsiz to recognise ESP   
   >   
   > there aren't any [SP] addressing modes in RM nor in PM except   
   > PUSH/POP/CALL/RET.   
   >   
   >> * addressable range will depend on DS.limit, not SS.limit   
   >> * linear address will depend on DS.base, not SS.base.   
   >   
   > this is wrong!   
      
   Agreed. Issue as above. SS.limit and SS.base will be used.   
      
   >   
   >> Note that it appears that the Big bit on DS (i.e. DS.B) is ignored   
   >> even though the instructions access DS. Also, the base and limit and   
   >> everything else from SS are ignored for those instructions.   
   >   
   >> The findings may be unexpected (they certainly surprised me) but see   
   >> the section entitled Segment Descriptors in CHAPTER 3 of   
   >> PROTECTED-MODE MEMORY MANAGEMENT in Intel manuals.   
   >   
   > such false statements are really printed in Intel docs ?   
      
   No, what Intel says is as follows. Remember this is about the B bit (aka   
   D bit on a code seg) which is supposed to be 0 for 16-bit and 1 for   
   32-bit operation - and which I think we disagree.   
      
      
      
      
   D/B (default operation size/default stack pointer size and/or upper   
   bound) flag   
      
   Performs different functions depending on whether the segment descriptor   
   is an executable code segment, an expand-down data segment, or a stack   
   segment. (This flag should always be set to 1 for 32-bit code and data   
   segments and to 0 for 16-bit code and data segments.)   
      
   • Executable code segment. The flag is called the D flag and it   
   indicates the default length for effective addresses and operands   
   referenced by instructions in the segment. If the flag is set, 32-bit   
   addresses and 32-bit or 8-bit operands are assumed; if it is clear,   
   16-bit addresses and 16-bit or 8-bit operands are assumed. The   
   instruction prefix 66H can be used to select an operand size other than   
   the default, and the prefix 67H can be used select an address size other   
   than the default.   
      
   • Stack segment (data segment pointed to by the SS register). The flag   
   is called the B (big) flag and it specifies the size of the stack   
   pointer used for implicit stack operations (such as pushes, pops, and   
   calls). If the flag is set, a 32-bit stack pointer is used, which is   
   stored in the 32-bit ESP register; if the flag is clear, a 16-bit stack   
   pointer is used, which is stored in the 16-bit SP register. If the stack   
   segment is set up to be an expand-down data segment (described in the   
   next paragraph), the B flag also specifies the upper bound of the stack   
   segment.   
      
   • Expand-down data segment. The flag is called the B flag and it   
   specifies the upper bound of the segment. If the flag is set, the upper   
   bound is FFFFFFFFH (4 GBytes); if the flag is clear, the upper bound is   
   FFFFH (64 KBytes).   
      
      
      
      
   That's all the Intel docs say in that section about the D/B flag. Some   
   points of note:   
      
   * The bit is in the last 16 bits of a descriptor so will be zero for   
   PM16 for which all those bits are expected to be zero.   
      
   * Although Intel say the bit should be set to 1 on all 32-bit segments,   
   according to the description Intel gives, above, the CPU doesn't check   
   the bit on any data segments other than SS.   
      
   * Even on the stack segment the bit still doesn't influence address size   
   or operand size of any explicit references to that segment.   
      
   IOW even if the B bit were to be clear on DS, ES etc you could still   
   access them as normal as 32-bit segments.   
      
   Going a little further, the B bit is distinct from the G (granularity)   
      
   [continued in next message]   
      
   --- 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