A question regarding unreal mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

A question regarding unreal mode

Post by limp »

Hi all,

I have a question regarding addressing in unreal mode.

AFAIK, real mode is a 20-bit addressing mode (i.e. 4 bits for the segment and 16-bits for the offset).
Let's say that we switch to PM and change the segment limit of the DS to 4GB. If real-mode uses ONLY 16-bit for the offset, then we're still limited to 1MB. The only way that "unreal mode" would work is if the offset is a 32-bit value but AFAIK it is a 16-bit value.

From "http://www.internals.com/articles/protmode/realmode.htm"
As you already know, a processor requires a minimum of 20 address lines to have the ability to access 1MB of memory. When Intel engineers designed the 8086, it was impracticle to implement a 20 bit address register to hold the generated addresses. So instead, Intel decided to divide address space into 64KB segments and coordinate memory access through the use of two 16 bit values - a Segment and an Offset.
From "http://www.ganssle.com/articles/aprot1.htm"
Real Mode addresses are limited to 20 bits, and are generated by adding a 16 bit segment register, shifted left four bits, to a 16 bit offset. This much maligned segmentation causes no end of grief for programmers trying to access large data structures. Since an offset cannot exceed 16 bits, you just can't increment beyond 64k; you'll have to watch for a 64k boundary and then play games with the segment register.
Any hints?

Thanks in advance.
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: A question regarding unreal mode

Post by Love4Boobies »

limp wrote:Let's say that we switch to PM and change the segment limit of the DS to 4GB. If real-mode uses ONLY 16-bit for the offset, then we're still limited to 1MB. The only way that "unreal mode" would work is if the offset is a 32-bit value but AFAIK it is a 16-bit value.
Heh. I don't follow your logic. Although I'm in unreal mode, real mode does it differently so how can I make it work? The only reason why segments have a 64 KiB limit (and thus take 16-bit offsets) is their limit - which you change to 4 GiB. Since real mode normally lets you access every address in the address space, it doesn't need to play with the cache descriptors which remain to the values you set in protected mode.

Long story short, you use 32-bit offsets.
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: A question regarding unreal mode

Post by ~ »

You also need to enable gate A20 to have a fully functional 4GB address space, both in Unreal Mode and in any other processor mode above standard 16-bit. Otherwise you will only be able to access even megabytes since the bit 20 of the address will be configured to stay "hardwired" to 0.

For the most part, real mode applications continue to work normally if they only use standard Real Mode addressing.

If your program requests 32-bit offsets it will no longer cause a CPU fault and a subsequent freeze.

If you want 32-bit offsets, you must use the following instructions, which would normally freeze the CPU in real mode:

1. The safest, easiest and more used method. It is more easily used if the segment register is set to 0 or if the 20-bit address representation of DS (default by CPU), ES, FS or GS is substracted from the 32-bit offset, to have a linear 4GB address space:

Code: Select all

push ds
  xor ax,ax         ;EAX=0
  mov ds,ax         ;Set DS to base address of 0
  mov eax,0x500000  ;Our 32-bit address


  ;The important part:
  ;;
   mov byte[eax],0xF4

pop ds

2. Substracting segment register:

Code: Select all

mov eax,0x500000  ;Our 32-bit address
xor ebx,ebx       ;Clear EBX...
mov bx,ds         ;         ...and load DS
shl ebx,4         ;Convert it to 20-bit address value
sub eax,ebx       ;Substract 20-bit DS to have linear 4GB


;The important part:
;;
 mov byte[eax],0xF4

3. Less reliable in theory (you will have to make your own tests to see if it's actually functional). Similar to 1 but using "a32" addressing override prefix to use 32-bit addressing:

Code: Select all

push ds
  xor ax,ax         ;EAX=0
  mov ds,ax         ;Set DS to base address of 0


  ;The important part:
  ;;
   a32 mov byte[0x500000],0xF4

pop ds
--------------------------------------------------
--------------------------------------------------

By default, instructions like LODSB/STOSB use SI and DI in Real Mode for string operations, so you will have to carefully use the "a32" prefix (to use 32-bit addressing) and the "o32" prefix (to use 32-bit operands --registers, immediate bytes...--) when using Unreal Mode.

The operand part would be more easily controlled by specifying LODSB, LODSW or LODSD, and the addressing part would be better controlled in this case by using the "a32" instruction prefix under Unreal Mode.

It is necessary to be careful with the instructions that behave differently in 16 and 32-bit modes from the point of view of their default addressing size and their default operand size (if any).
Last edited by ~ on Tue Mar 09, 2010 11:15 am, edited 1 time in total.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: A question regarding unreal mode

Post by qw »

The trick is this: if in real mode a segment register is loaded with some value, the base field of the descriptor cache is adjusted, but the limit field is not. So if the limit was set to 4 GiB, it stays 4 GiB, and you may directly address 0x12345678 (if there is memory there).
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: A question regarding unreal mode

Post by limp »

Thank you all for your responses, they really helped me to understand how this works.

I knew that the offset under real-mode should be fixed to 16-bits and not that its size depends on the desciptor's limit value. Another thing I assumed is that under real-mode, no matter what you do, you have 20-bit addressing but as it seems, you can have up to 32-bit addressing using a segment limit of 4GB.
~ wrote:You also need to enable gate A20 to have a fully functional 4GB address space, both in Unreal Mode and in any other processor mode above standard 16-bit. Otherwise you will only be able to access even megabytes since the bit 20 of the address will be configured to stay "hardwired" to 0.
I have one question regarding this gate-A20 thing. For any access below 1MB I should have gate-A20 disabled, right?
If I have it set from the begging, I can only use the address range (100000-10FFEFh) - high memory area (HMA) so, I should enable it only at the time I want the extra range if I understood correctly.

Now, I didn't know that gate-A20 should be enabled under PM as well...So, if it is enabled and I want to use a pointer that points to a memory address which is below 1MB should I disabled it for doing this access and then re-enabling it?

Thanks again for your time and the useful responses.
Last edited by limp on Sat Oct 16, 2010 7:36 am, edited 2 times in total.
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: A question regarding unreal mode

Post by Firestryke31 »

You do not need to disable A20 unless you're using poorly written software. A20 only makes it so you have the ability to use every other megabyte, it does not disable anything.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: A question regarding unreal mode

Post by Gigasoft »

Yeah, there's no reason to leave the A20 gate disabled. When the A20 gate is enabled, all physical addresses are left unchanged. The only reason for leaving the A20 gate disabled is to run 8086 programs that rely on addresses wrapping at 1MB, of which there are none that I know of.

The offset size is independent of the segment limit. In real mode, the default offset size is always 16 bits, and the 67h prefix changes it to 32 bits. However, with the default limit of 0ffffh, an offset that causes the last byte of the access to exceed 0ffffh is invalid.
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: A question regarding unreal mode

Post by limp »

Firestryke31 wrote:You do not need to disable A20 unless you're using poorly written software. A20 only makes it so you have the ability to use every other megabyte, it does not disable anything.
So, it's not setting the 21st bit of the address?? If it is actually setting the 21st address bit, if I want to access something below 1MB how can is it possible if the 21st bit of the adddress is always enabled (i.e. minimum address of 1MB - 0x100000) ?

Thanks,
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: A question regarding unreal mode

Post by ~ »

limp wrote:So, it's not setting the 21st bit of the address?? If it is actually setting the 21st address bit, if I want to access something below 1MB how can is it possible if the 21st bit of the adddress is always enabled (i.e. minimum address of 1MB - 0x100000) ?

Thanks,

A20 disabled == bit 20 of address bus "hardwired" to 0

A20 enabled == bit 20 of address is now capable of working normally like the rest of address bits
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: A question regarding unreal mode

Post by Firestryke31 »

Basically, it does not set any address bits, it merely allows you to use address bit 20.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
limp
Member
Member
Posts: 90
Joined: Fri Jun 12, 2009 7:18 am

Re: A question regarding unreal mode

Post by limp »

~ wrote:
limp wrote:So, it's not setting the 21st bit of the address?? If it is actually setting the 21st address bit, if I want to access something below 1MB how can is it possible if the 21st bit of the adddress is always enabled (i.e. minimum address of 1MB - 0x100000) ?

Thanks,

A20 disabled == bit 20 of address bus "hardwired" to 0

A20 enabled == bit 20 of address is now capable of working normally like the rest of address bits
Ok, now it is clearer, thanks!
Gigasoft wrote:The offset size is independent of the segment limit. In real mode, the default offset size is always 16 bits, and the 67h prefix changes it to 32 bits. However, with the default limit of 0ffffh, an offset that causes the last byte of the access to exceed 0ffffh is invalid.
Could you be a bit more specific on this please -> the 67h prefix changes it to 32 bits

Thanks,
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: A question regarding unreal mode

Post by ~ »

limp wrote:Could you be a bit more specific on this please -> the 67h prefix changes it to 32 bits

The 67h prefix is the same as "a32" keyword in NASM, like in:

a32 mov ax,[3]

To have a 32-bit address in the [3] part.
User avatar
qw
Member
Member
Posts: 792
Joined: Mon Jan 26, 2009 2:48 am

Re: A question regarding unreal mode

Post by qw »

~ wrote:The 67h prefix is the same as "a32" keyword in NASM, like in:

a32 mov ax,[3]

To have a 32-bit address in the [3] part.
Be careful with that. Older versions of NASM will emit 67A10300 instead of 67A103000000. To be safe, you should use:

Code: Select all

mov ax, [dword 3]
Post Reply