flat assembler
Message board for the users of flat assembler.

Index > DOS > Question about real mode addressing

Goto page 1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
Dasn



Joined: 22 Nov 2004
Posts: 10
Dasn
I would treat "real mode" addressing as the same as 8086 addressing (don't know if it's right Smile ) which shifts its segment register 4-bit left and adds the offset to it to generate the final physical memory address. For example:
[Address1]:
0008:1111 -> 01191

0008
+1111
01191

[Address2]:
0009:1101 -> 01191

0009
+1101
01191

Note that, they are different segments and offsets, but generate the same physical memory address. First I assume they are the same addresses. To test what I thought, I try to write one byte of value into Address1 and then read from Address2, but the value returned is not the same as what I just stored. (I've tested it in Dosbox and Qemu). So, that means Address1 and Address2 are not the same place. I got so confused, what's the trick here? Thanks.
Post 11 Jan 2009, 08:04
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
> First I assume they are the same

Right. There are only 2^20 different addresses, not 2^32, in 8086's addressing space.

> write one byte of value into Address1 and then read from Address2,
> but the value returned is not the same as what I just stored.

Then you simply did something wrong Smile

> (I've tested it in Dosbox and Qemu).
> So, that means Address1 and Address2 are not the same place.

They are. Try in DOS. BTW, if you "open" 1'000'000 DOG-BOX'es inside a non-DOS system, they will be "isolated" from each other as well as from real physical memory, and such tests simply must fail Crying or Very sad

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 11 Jan 2009, 08:48
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4242
Location: 2018
edfed
to be valid, thesevalues should be represented in HEXADECIMAL.
because in decimal,it is not the same.

[0008:1111h]=[1191h]
[0009:1101h]=[1191h]

with decimal values, it gives:

[8:1111]=[1239]
[9:1101]=[1245]
Post 11 Jan 2009, 09:19
View user's profile Send private message Visit poster's website Reply with quote
Dasn



Joined: 22 Nov 2004
Posts: 10
Dasn
edfed wrote:
to be valid, thesevalues should be represented in HEXADECIMAL.
because in decimal,it is not the same.

[0008:1111h]=[1191h]
[0009:1101h]=[1191h]

with decimal values, it gives:

[8:1111]=[1239]
[9:1101]=[1245]


Hi guys, thank you all.
Just as 'edfed' pointed, I used the wrong representation of the numbers. I wrongly use "mov byte [ds:1111], 'A' " to store the byte in my code. The result is correct now.

Then this raise another problem in 'real mode addressing', ie. as we can see, the addresses can be easily overlapped if they are not be calculated carefully. Are there some ways to avoid this problem when programming with multiple segments in real mode?
For example, using '0x1000', 0x2000, 0x3000 ... as segment should jump over this problem, but how to do with the segments less than 0x1000?

Thanks again.
Post 11 Jan 2009, 10:46
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
Quote:
Then this raise another problem in 'real mode addressing', ie. as we can see, the addresses can be easily overlapped if they are not be calculated carefully. Are there some ways to avoid this problem when programming with multiple segments in real mode? For example, using '0x1000', 0x2000, 0x3000 ... as segment should jump over this problem, but how to do with the segments less than 0x1000?


http://www.ctyme.com/intr/rb-2934.htm

You can't use just any address, you must hog memory from DOS, and use what ou get.

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 11 Jan 2009, 11:34
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
Dasn wrote:
…how to do with the segments less than 0x1000?
Use 0x0000 as the segment selector. Wink
Post 13 Jan 2009, 04:14
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
Just got back from my summer holiday... We're having some great weather here in NZ (for those of us who are not farmers Wink ). Over 3 weeks with sun and no rain!


You can guarantee no overlapping if segment regs are always x000h i.e use 4 most significant bits to select the required 64K segment using 16-bit offsets. This gives you access to the "entire" 1 Mbyte of conventional memory, with 16 segments 0000, 1000h, .... f000h.

Of course if you switch to (un- or flat) real mode and use 32-bit offsets you need only one "segment" 0000, and you have access to 4 Gbytes of memory. Each with a unique 32-bit address, no overlapping guaranteed!

_________________
FAMOS - the first memory operating system
Post 15 Jan 2009, 22:16
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
neville,

Even slightly more than 1 MiB, with A20 gate enabled…

Don't you know that 0…3 selectors are reserved in PM? Wink

It's snowy here… Wink
Post 15 Jan 2009, 23:10
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
baldr,

Quote:
Even slightly more than 1 MiB, with A20 gate enabled…

I did say 1 Mbyte of *conventional* memory, which in DOS terms finishes at F000:FFFFh

I think you are referring to the HMA or "High Memory Area", which in DOS terms resides *above* conventional memory, and can be accessed with 16-bit offsets using segment FFFFh i.e. FFFF:0010h - FFFF:FFFFh, 16 bytes less than 65536 = 65520 bytes. As linear addresses the HMA is 100000h - 10FFEFh and A20 is obviously required for all addresses above F000:FFFFh = FFFFFh linear.

Quote:
Don't you know that 0…3 selectors are reserved in PM?

I don't know what this means. Is it relevant to real mode addressing??

_________________
FAMOS - the first memory operating system
Post 16 Jan 2009, 01:57
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
neville,

Yes, I was referring the HMA. Conventional memory spans 0…9FFFF range, A0000…FFFFF is the upper memory area.

Selectors 0…3 (called NULL segment selectors) are reserved in the sense that you can load them into the segment registers (except cs and ss, obviously), but any access will cause #GP fault.

Intel SDM states that CPU will load descriptor from GDT upon loading NULL selector (I highly doubt it, pseudocode even doesn't check GDT limit), AMD APM says something different. I'll check it later.

It is relevant to unreal mode. You definitely can't have 0 in ss (unless your stack is 64 KiB), and other segregs are questionable (except cs, of course).

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 16 Jan 2009, 05:30
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 713
Location: Adelaide
sinsi
baldr wrote:
It is relevant to unreal mode. You definitely can't have 0 in ss (unless your stack is 64 KiB), and other segregs are questionable (except cs, of course).

In unreal mode, your stack is limited to 64K anyway as long as you don't load SS when you are (briefly) in PM. SS:SP as 0000:7c00 is perfectly valid in unreal mode.
The only way to access > 1MiB is to go to PM, load a segment register with a 4GiB selector, back to RM, load the segment register with 0. No selectors used any more (because we're in real mode) so SS is just a segment, not a selector.
Post 16 Jan 2009, 05:48
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
sinsi, please read latest manual. Even in RM segment registers contain selectors. Wink
Post 16 Jan 2009, 08:09
View user's profile Send private message Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 713
Location: Adelaide
sinsi
Yes. the 'hidden' part, but if you don't load a segment in PM with a selector it doesn't matter.
Post 16 Jan 2009, 08:16
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
sinsi, hidden part contains descriptor (base, limit and access rights). Even in RM. That's why unreal mode exists.
Post 16 Jan 2009, 09:01
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
baldr wrote:
Don't you know that 0…3 selectors are reserved in PM? Wink

The relevance of this statement to real or unreal mode still escapes me. In unreal mode you can load any of the segment registers with any 16-bit value and the CPU is perfectly happy.

However, if your statement is related to the fact that the first entry in any GDT is a NULL entry, then that is relevant only when actually in (or entering) protected mode.

Is this a case of deliberate attempted confusion, or just talking in riddles? Wink

_________________
FAMOS - the first memory operating system
Post 16 Jan 2009, 18:36
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
neville,

That's heavy… Wink
neville wrote:
Of course if you switch to (un- or flat) real mode and use 32-bit offsets you need only one "segment" 0000, and you have access to 4 Gbytes of memory. Each with a unique 32-bit address, no overlapping guaranteed!
Please explain what have you meant by "segment" 0000? I took it for selector value of 0, thus my rant… Wink

CPU is happy because it make itself happy: when (in RM) you load selector X in segment register, corresponding descriptor is loaded with base X*16, limit 0xFFFF and appropriate rights/flags.

I'd reread Intel SDM again, here's the fragment:
Quote:
MOV—Move

A NULL segment selector (values 0000-0003) can be loaded into the DS, ES, FS and GS registers without causing a protection exception. However, any subsequent attempt to reference a segment whose corresponding segment register is loaded with a NULL value causes a general protection exception (#GP) and no memory reference occurs.

IF DS, ES, FS, or GS is loaded with NULL selector
THEN
SegmentRegister ← segment selector;
SegmentRegister ← segment descriptor;
FI;
Weird, eh? I'll try to clear this out (GDT with limit<7, do the descriptor loaded indeed, and such), but it will take time…

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 16 Jan 2009, 20:16
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
baldr,
Quote:
Please explain what have you meant by "segment" 0000? I took it for selector value of 0, thus my rant…
In real mode or unreal mode when I load a segment register, I am writing only a 16-bt value. AFAIK it is not a "selector value" because no GDT or LDT exists any more, so the CPU does not have any "limit" or "base" to read.

e.g.
Code:
     XOR     AX,AX
       MOV     DS,AX           ;DS=0000 (16 bits!)    
Your reference suggests that the CPU actually uses a default limit of FFFFh in RM but if that is true it would overwrite the 32-bit limit of FFFFFFFFh previously set up in PM before jumping back to (un)real mode?

So are you saying that unreal mode is not really real mode? (in which case I am guilty of straying off-topic by introducing unreal mode ina real-mode discussion thread Wink )

Actually it may be that the CPU is always really in PM, but only implements RM by "emulating" RM addressing e.g using base=segreg*16 etc. ??

Or is the truth that the CPU is actually always in RM, but implements PM by activating the selector logic....

_________________
FAMOS - the first memory operating system
Post 16 Jan 2009, 21:13
View user's profile Send private message Visit poster's website Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 713
Location: Adelaide
sinsi
baldr, from the latest Intel docs
Quote:
In real-address mode, the processor does not interpret segment selectors as indexes
into a descriptor table; instead, it uses them directly to form linear addresses as the
8086 processor does. It shifts the segment selector left by 4 bits to form a 20-bit base address.
Post 17 Jan 2009, 01:46
View user's profile Send private message Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
baldr
neville,

Even in PM you load 16-bit selector. In RM this loads predefined values to base, limit and rights fields of corresponding hidden descriptor (base of selector*16, limit of 65535, proper rights for code/data segment). In PM CPU will use indicated GDT/LDT entry.

Unreal mode is real mode with non-standard segment descriptors loaded. Each time you load segment register, unreal mode become more and more real. Wink

sinsi,

I don't believe that CPU makers use too much dedicated circuitry for RM logical-to-linear mapping. Do you see flaws in my speculations about loading artificial descriptor when loading segment register? Intel docs specify what happens, not how.

_________________
"Don't belong. Never join. Think for yourself. Peace." – Victor Stone.
Post 17 Jan 2009, 20:09
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1901
DOS386
baldr wrote:
Each time you load segment register, unreal mode become more and more real.


Doesn't it cancel immediately ?
Post 18 Jan 2009, 08:36
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2, 3, 4  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.