Well, the documentation I gave on the first post says something interesting on it:
Sometimes the arithmetic is dependent upon the B (Big) bit in the DTE. This bit controls several aspects of how the CPU interpre […]
Show full quote
Sometimes the arithmetic is dependent upon the B (Big) bit in the DTE. This bit controls several aspects of how the CPU interprets the Base, Limit, and Valid Offsets of a selector. As you can see from the table below, the B bit has a huge effect on how Expand Down segments are described and no effect on Expand Up segments. Because the arithmetic is done modulo either 64KB (for B=0) or 4GB (for B=1), we define the Modulus to be 64KB for B=0, and 4GB for B=1.
Stack Type Expand Up Expand Down
GDT/LDT Base LA LA + Length - Modulus
GDT/LDT Limit Length - 1 (Modulus - 1) - Length
Smallest Offset 0 Modulus - Length
Largest Offset Length - 1 Modulus - 1
Initial eSP Length 0
That first field(GDT/LDT Base) got me thinking...
So the base is LA(which is the base)+FFFF(length)-FFFFh(FFFFFFFFh for 4G granularity)(modulus) in the case of said 64K segment(although at that size, according to documentation, it disappears(due to the offset being <=limit always, thus no valid offsets)). Thus 0x80000000+ffffh(length)-ffffh(modulus)=0x80000000 as it's base. But when the length field is decreased, said address becomes closer to 0x80000000(still ending at the byte before it?)? So a size of limit field 0x7FFF(32K being addressable at the end of the segment) becomes a base of 0x7FFF8000(80000000h+7FFFh-FFFFh), with it's final byte(offset FFFFh added to that) at 80007FFF(thus the linear address ending like a plain 32K segment in memory)?
So perhaps that "LA+Length-Modulus"(Just LA for Expand-Up descriptors, Length being the limit field(expanded to 4G pages if the B-bit is set(filling the lower 12 bits with FFFh)) and Modulus being FFFFh or FFFFFFFFh depending on the granularity) is the actual formula used by a CPU for it's adding to the offset? If that's true, the OS can simply program the base to where it wants to put the data in memory(for example 0x80000000 in my example), without having to worry about a Expand-Up or Expand-Down segment is used. The block stays at the same address when the limit field is decreased(increasing the stack size for example, the OS just needs to move it's data ahead by the amount of bytes that are added to the segment). In the case of 4K pages(assuming the base address is 4K aligned), this is even easier(just modify the paging unit and map all pages one or more pages ahead).
Edit: The text further ahead seems to verify that information I mentioned above(in my bottom examples):
For Expand Up segments, the GDT/LDT Base Address is fixed at LA, and for Expand Down segments it's LA + Length - Modulus. As Length increases up to and including Modulus, the Base Address approaches LA (the same as for Expand Up segments).
This illustrates the great benefit of an Expand Down data segment when used as a stack. Because stacks grow downward, when they overflow, the stack can be expanded easily by copying its data to the top of a new (and larger) area of memory and then pointing the stack selector to the new location. Note that references to items on the stack do not change when the stack expands because the upper limit of the stack does not change and offsets in an Expand Down stack are all relative to the top of the stack.
In a similar manner, an Expand Up segment grows upward, so it can be expanded by copying its data to the bottom of a new (and larger) area of memory and then pointing the data selector to the new location. Here, too, references to items in the data segment do not change when the data segment expands because the start of the segment (offset zero) does not change and offsets in an Expand Up segment are all relative to the bottom of the data segment.
If the base fields of the descriptor behaved the same in both Expand-Up and Expand-Down descriptors, said quotes would make little sense. It clearly says that the data is copied to the top of the new segment with Expand-Down descriptors and to the bottom of an Expand-Up descriptor. If the base field would just be added to the offset(e.g. FFFFh) in such a case, you'll end up 32K past any data you would copy(in my example above) instead of the correct location(which is at 0x80000000-0x800007FFF.
If the base would function the same way (just being added to the offset without substracting (FFFF)FFFFh and the limit from it), said explanation quoted would break all code that uses said logic?