real mode memory addressing

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.
User avatar
VolTeK
Member
Member
Posts: 815
Joined: Sat Nov 15, 2008 2:37 pm
Location: The Fire Nation

real mode memory addressing

Post by VolTeK »

ok i know this may be a dumb question but i just want to make sure

8000:1234 = 81234h? just like 8123:0004 would equal the same?

for all i understand say the bootloader is 0000:7c00
could i do this

1000: 0000-ffff = 64 kb 10000h to 1ffffh
then 2000: 0000- ffff another 64 kb 20000h- 2ffffh
am i able to acsess this with no problems, i know at for example i have to watch out for example 0xb800 but do i have to watch out for that in every segment? do i have to watch out for

0000:b800
1000:b800
2000:b800

im sorry if this is all confusing to ask, but im trying to kill two birds with one stone
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: real mode memory addressing

Post by neon »

GhostXoPCorp wrote:8000:1234 = 81234h? just like 8123:0004 would equal the same?
No. The formula to convert a segment:offset address to a linear address is segment*16 (decimal)+offset. So, 8000:1234 = 8000*16+1234 = 0x1F8D2 (assuming all numbers are decimal.)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: real mode memory addressing

Post by NickJohnson »

Yes, that's right (assuming all numbers are hexadecimal; I'm omitting the 0x and h for brevity here too). However, I think you're a bit confused about the second part - you have to "worry about" B800:XXXX, not XXXX:B800, in order to not overwrite video memory, because video memory is at B800:0000 (B8000). XXXX:B800 is always free as long as XXXX is less than A800 - otherwise you hit video memory and BIOS stuff (also watch out for the BDA and IVT).
User avatar
VolTeK
Member
Member
Posts: 815
Joined: Sat Nov 15, 2008 2:37 pm
Location: The Fire Nation

Re: real mode memory addressing

Post by VolTeK »

thnaks nick, now i know that its the segment i should look out for. and thanks neon for the equation, but how should i count up, when i get to ffff in the offset should i add one to the segment? i tried calculating that and its very out of wack just counting up the way i did. how can i make it all go in order, could some one point me to a link or give me an explanation :D im sorry if i ask too much
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: real mode memory addressing

Post by neon »

GhostXoPCorp wrote:but how should i count up, when i get to ffff in the offset should i add one to the segment?
Try it like this:

Code: Select all

0:0xffff = 0xFFFF
0x1000:0x0 =    0x10000 < This is (0:0xFFFF+1)
0x2000:0x0 =    0x20000 < This is ( 0x1000:0xFFFF+1)
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
VolTeK
Member
Member
Posts: 815
Joined: Sat Nov 15, 2008 2:37 pm
Location: The Fire Nation

Re: real mode memory addressing

Post by VolTeK »

well say i want to accsess 10002 could u give me the equation on accsessing that? i promise thats the last question, i should be able to understand after this
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: real mode memory addressing

Post by neon »

GhostXoPCorp wrote:well say i want to accsess 10002 could u give me the equation on accsessing that? i promise thats the last question, i should be able to understand after this
There is 4096 segment:offset addresses that refer to that same byte in memory. There is no simple way to obtain a specific segment:offset address from the linear one. You should be thinking in terms of segment:offset not linear addresses in real mode.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
VolTeK
Member
Member
Posts: 815
Joined: Sat Nov 15, 2008 2:37 pm
Location: The Fire Nation

Re: real mode memory addressing

Post by VolTeK »

ok, thank u neon and nick for answering my questions, my purpose is that im making something pretty big, well to me, and i need some heads up on wat to expect and if i already know it or if theres something i need to know before i go through with it. ill update me sig so everyone knows wat im talking about
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: real mode memory addressing

Post by Ready4Dis »

8000h * 10h (16 decimal) = 80000h, that plus 1234h = 81234h. 8123h:0004h also comes out to 81234h.

*** Edit ***
Fixed my post, didn't realize neon said decimal
Last edited by Ready4Dis on Thu Nov 19, 2009 9:13 am, edited 1 time in total.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: real mode memory addressing

Post by Ready4Dis »

GhostXoPCorp wrote:well say i want to accsess 10002 could u give me the equation on accsessing that? i promise thats the last question, i should be able to understand after this
Sure, 1000h:0002h [Seg:Offset], just like you were thinking in your first post.

*** Edited this one to... ***
Last edited by Ready4Dis on Thu Nov 19, 2009 9:13 am, edited 1 time in total.
User avatar
f2
Member
Member
Posts: 311
Joined: Mon Jun 15, 2009 10:01 am
Location: France

Re: real mode memory addressing

Post by f2 »

Ready4Dis wrote:
neon wrote:
GhostXoPCorp wrote:8000:1234 = 81234h? just like 8123:0004 would equal the same?
No. The formula to convert a segment:offset address to a linear address is segment*16 (decimal)+offset. So, 8000:1234 = 8000*16+1234 = 0x1F8D2 (assuming all numbers are decimal.)
What are you talking about man?

8000h * 10h (16 decimal) = 80000h, that plus 1234h = 81234h. Where did you come up with 0x1f8d2? His maths were correct. did you multiply the offset by 16 then add the segment? Same thing in his second example, 8123h:0004h does come out to 81234h.
@Ready4Dis: :!: Have you read Neon's post correctly? He says: "assuming all numbers are decimal".
So, 8000:1234 = 8000*16+1234 = 129234 = 0x1F8D2. This is correct.
Of course, you're also right: 8000h:1234h = 8000h*16+1234h = 81234h.
"Open source seems to embrace the dark side of human nature." - Ville Turjanmaa
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: real mode memory addressing

Post by Ready4Dis »

I typically like to think linearly in real mode, and convert when I need to, makes it simpler for me.

When I have a linear address I want to convert, it's very simple:

Segment = Linear / 16
Offset = Linear % 16

(Or, in simpler terms)
Segment = Linear>>4;
Offset = Linear & 15;

Of course this doesn't *always* work, like if you're trying to access 0x10ffef (0xffff:0xffff), it won't calculate correctly. There are some ways around it, and probably another equation you could use that would work.

For example:

Code: Select all

If linear >= 0x100000 then  //check to see if our equation won't work for this one
  Linear -= 0xffff;
  Offset= 0xffff;
  Segment = Linear>>4;
else
  Segment = Linear>>4;
  Offset = Linear & 15;
end if
A little more work, but it'll work in all cases now.

*** Edit ***
Just wanted to add, in order to access over 0x100000 you have to make sure your A20 is disabled first, so more often than not, this extra work to fix these cases is irrelevant and you can just use the first example if you stay under 1mb. If you want to wrap around just like the A20, you can do this:
Segment = (Linear>>4) & 0xfff;
Offset = Linear & 15;
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Re: real mode memory addressing

Post by Ready4Dis »

Tommy wrote: @Ready4Dis: :!: Have you read Neon's post correctly? He says: "assuming all numbers are decimal".
So, 8000:1234 = 8000*16+1234 = 129234 = 0x1F8D2. This is correct.
Of course, you're also right: 8000h:1234h = 8000h*16+1234h = 81234h.
Apparently I didn't :oops: . I saw his answer was written in hex and figured he did the entire thing as hex. I thought it was pretty clear the OP was talking about hex (7c00 can't really be decimal can it?), and completely missed the part were he said decimal.

Appologizes, and I will edit my posts so nobody gets confused :P.
User avatar
VolTeK
Member
Member
Posts: 815
Joined: Sat Nov 15, 2008 2:37 pm
Location: The Fire Nation

Re: real mode memory addressing

Post by VolTeK »

so i can -

1000:0000 - ffff when i get to ffff then -
2000:0000 - ffff untill i hit f000:ffff?
User avatar
Love4Boobies
Member
Member
Posts: 2111
Joined: Fri Mar 07, 2008 5:36 pm
Location: Bucharest, Romania

Re: real mode memory addressing

Post by Love4Boobies »

Argh. Just look below.

Code: Select all

SSSSSSSSSSSSSSSS
    OOOOOOOOOOOOOOOO
--------------------
AAAAAAAAAAAAAAAAAAAA
The Ses represent the bits of the segment selector.
The Os represent the bits of the offset.
The As represent the bits of the linear address you get as a result.

As you can see, 12 of the Ses and Os overlap so you can make up a lot of combinations of them (e.g. 0 + 1 or 1 + 0) to get the same result - as neon said, there's 4096 possible combinations that address one single byte (except for the first and last few byes). Can it be explained any easier to you?
"Computers in the future may weigh no more than 1.5 tons.", Popular Mechanics (1949)
[ Project UDI ]
Locked