[comp.sys.intel] 386 "real" mode access beyond 1M using data_32 instruction prefix

tony@h-three.UUCP (me) (02/13/89)

I need to write a routine for a 386 in "real" mode (actually a firm-
ware application) that can read/write data above 1M.  At first glance,
the instruction and address prefixes (0x66, 0x67) would seem to be
the way to do this; but I can't get them to work, and even have a 
suspicion they won't work.

Here is the current test routine (assembler is right to left w operands).
The routine takes a physical address and a 32 bit value to put there.
Technique is to zero 'es' and stick the address into 'esi'.  Theory is
that will yield:    effective address == (0 << 4) + esi

This routine fails with General Prot Fault (13).

| void m32poke(addr, value)
| u32 addr, value;

#include	"sys/mch.h"
#include	"asm.h"

	.globl	_m32poke
_m32poke:	
	push	bp		    | C linkage
	mov	bp,sp
	push	si

	xor	ax,ax		    | es to zero as base
	mov	es,ax

	.byte   0x66		    | 32bit prefix
	mov	si,*4(bp)	    | si=address
	.byte	0x66
	mov	ax,*8(bp)	    | ax=value

	.byte	0x66		    | GP 13 fault points here!
	.byte	0x67
	seg	es
  	mov	(si),ax	

	pop	si
	pop	bp
	ret

Is this the wrong way to do this?

Is it even possible to access above 1M without going into full protected
mode?
-- 
--tony	 ...!uunet!h-three!tony	 (919) 549-8334	 h-three  Systems  Corporation
	 h-three!tony@uunet.uu.net		 POB 12557; RTP, NC 27709; USA
						 t. e. bennett

paula@bcsaic.UUCP (Paul Allen) (02/15/89)

In article <529@h-three.UUCP> tony@h-three.UUCP (me) writes:
>I need to write a routine for a 386 in "real" mode (actually a firm-
>ware application) that can read/write data above 1M.  At first glance,
>the instruction and address prefixes (0x66, 0x67) would seem to be
>the way to do this; but I can't get them to work, and even have a 
>suspicion they won't work.

	[assembly code that gets General Protection Fault]

>Is this the wrong way to do this?
>
>Is it even possible to access above 1M without going into full protected
>mode?

I was curious about this too, so I walked over to our library and
checked a 386 reference.  It turns out that the answer is both yes and
no.  In real mode, the offset part of an address is always treated as
16 bits, regardless of any 32-bit prefixes you specify.  The highest
address you can reach in real mode without triggering a General
Protection Fault is FFFF:FFFF, which is almost 64K more than 1Mb.  The
386 does not wrap around at the 1Mb boundary like the 8086 does.  In
general, you must switch to protected mode in order to use memory above
1Mb.

Paul Allen

-- 
------------------------------------------------------------------------
Paul L. Allen                       | pallen@atc.boeing.com
Boeing Advanced Technology Center   | ...!uw-beaver!ssc-vax!bcsaic!pallen

chasm@killer.DALLAS.TX.US (Charles Marslett) (02/16/89)

In article <529@h-three.UUCP>, tony@h-three.UUCP (me) writes:
> I need to write a routine for a 386 in "real" mode (actually a firm-
> ware application) that can read/write data above 1M.  At first glance,
> the instruction and address prefixes (0x66, 0x67) would seem to be
> the way to do this; but I can't get them to work, and even have a 
> suspicion they won't work.
> 
> Here is the current test routine (assembler is right to left w operands).
> The routine takes a physical address and a 32 bit value to put there.
> Technique is to zero 'es' and stick the address into 'esi'.  Theory is
> that will yield:    effective address == (0 << 4) + esi
> 
> This routine fails with General Prot Fault (13).

It certainly does: Intel (for reasons known only to their architects, real
world programmers would have never done it that way!) always verifies that
the address generated in real mode is less than 00110000h (so the 386 cannot
access any more real-mode memory than the 286.

You would have thought they should have learned a lesson from the 286's
one way mode switch . . . programmers like to be able to make mistakes!
Idiot proofing an instruction set makes it an idiot's instruction set.

> Is it even possible to access above 1M without going into full protected
> mode?

Nope....

> -- 
> --tony	 ...!uunet!h-three!tony	 (919) 549-8334	 h-three  Systems  Corporation
> 	 h-three!tony@uunet.uu.net		 POB 12557; RTP, NC 27709; USA
> 						 t. e. bennett

===========================================================================
Charles Marslett
STB Systems, Inc.  <== Apply all standard disclaimers
Wordmark Systems   <== No disclaimers required -- that's just me
chasm@killer.dallas.tx.us

wbeebe@bilver.UUCP (bill beebe) (02/18/89)

In article <7187@killer.DALLAS.TX.US> chasm@killer.DALLAS.TX.US (Charles Marslett) writes:

>It certainly does: Intel (for reasons known only to their architects, real
>world programmers would have never done it that way!) always verifies that
>the address generated in real mode is less than 00110000h (so the 386 cannot
>access any more real-mode memory than the 286.
>
>You would have thought they should have learned a lesson from the 286's
>one way mode switch . . . programmers like to be able to make mistakes!
>Idiot proofing an instruction set makes it an idiot's instruction set.
>
>> Is it even possible to access above 1M without going into full protected
>> mode?
>
>Nope....
>

The 80386 addresses the same amount of "real" address as the 80286 as does
the 8086. This is called backward compatibility and provides an easy path
from the original up to the 80386 and beyond. As far as addressing memory
above 1 meg, there are several ways the 80386 can do this. The first does
not require full protection, and allows special LIM emulation drivers and
Windows 386 to access the high (> 1 meg ) memory. The 80386 supports paging
where a logical address is translated into a physical address. You can
use this method to access code and data stored in the higher address.
In fact, when the original Intel 301 was introduced, they also sold software
from Phoenix Software called Control386. This software used paging to
backfill the 301's DOS memory from 512K up to 640K by paging memory
installed above 1 meg. This was 32-bit memory and when running had
absolutely no impact on real-mode DOS programs.

The second method, protected mode, can be switched into and out of under
software control by setting the Protection Enable bit of Control Register
0. This is a great oversimplification. If you want more information, you
should read chapters 10 and 14 of the 1986 80386 Programmer's Reference
Manual. In any event, once protected mode is entered and a _proper_
environment created, the 80386 can address any location in 4 Gbytes of
physical memory. The 80386 is also not limited to a 64K segment
limitation in protected mode. With the granularity bit clear in the
descriptor, segments can have a maximum limit of 1 meg. With the
granularity bit set, segments can have a maximum limit of 4 Gbytes.