Well I admit I said something wrong. I especially tested what you say. Well the test showed folling:
Code: Select all
MOV eax, cr0
OR al, 1
MOV cr0, eax
MOV ax, 0x10
MOV ES, ax
MOV eax, cr0
AND al, 0xFE
MOV cr0, eax
JMP 0x1000:$+5
a32 MOV word[ES:0xB8000], 0x0F00+'A'
XOR ax, ax
MOV ES, ax
a32 MOV word[ES:0xB8002], 0x0F00+'B'
MOV ax, 0x10
MOV ES, ax
a32 MOV word[ES:0xB8004], 0x0F00+'C'
MOV ax, 0x12
MOV ES, ax
a32 MOV word[ES:0xB8004], 0x0F00+'D'
CLI
HLT
Real -> Seg.selector * 16 + Offset (limit = 1MB)
Protected -> Seg.base + Offset (limit = 4GB <depends on the descriptor>)
Unreal (before change the segment) -> Seg.base + Offset (limit = 4GB <depends on the descriptor>)
Unreal (after change the segment) -> Seg.selector * 16 + Offset (limit = 4GB <descriptor changed, but...?>)
I will not argue without a reason. Yes I was wrong thinking that Seg.selector affects address just after entering unreal mode. But I admit you say the truth for everything. As I mentioned changing the CPU mode does not change how the segment addresses.
As it see from the test after enters unreal mode, descriptor base of ES is still used and
ES:0xB8000 = 0x0 + 0xB8000 = 0xB8000.
Then reload the segment to 0. This time mode for CPU is
real and it multiplies selector by 16 so
ES:0xB8002 = 0x0 *16 + 0xB8002 = 0xB8002. That is exactly what you say.
Next I loaded 0x10 in the segment. I assume you are right and 0x10 is a threated as a selector to some virtual GDT (we are in real mode) that actually points to 0x100.
ES:0xB8004 = 0x10*16 + 0xB8004 = 0x100 + 0xB8004 = 0xB8104
Theoritically that could be possible, but 0x12 is selector that should point to the same descriptor at different privelege level, well actually I get this:
ES:0xB8006 = 0x12*16 + 0xB8006 = 0x120 + 0xB8006 = 0xB8126.
Then not included here even after changing the selector I still able to read/write locations such as: ES:0xD8000000 = 0x0 * 16 + 0xD8000000 = 0xD8000000. So not only I can present invalid selector while in (un)real mode, but also the limit is 4GB.
So this test shows how the base address is made in all modes, but what about the limit. You see, Seg.base is not used after reload the segment in unreal mode. But the limit is still 4GB. If Seg.limit (and granularity bit) is used to make the limit, then no way hidden part to be changed while unreal mode.