real mode memory addressing
real mode memory addressing
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
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
Re: real mode memory addressing
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.)GhostXoPCorp wrote:8000:1234 = 81234h? just like 8123:0004 would equal the same?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
- NickJohnson
- Member
- Posts: 1249
- Joined: Tue Mar 24, 2009 8:11 pm
- Location: Sunnyvale, California
Re: real mode memory addressing
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).
Re: real mode memory addressing
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 im sorry if i ask too much
Re: real mode memory addressing
Try it like this:GhostXoPCorp wrote:but how should i count up, when i get to ffff in the offset should i add one to the segment?
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();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: real mode memory addressing
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
Re: real mode memory addressing
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.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
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Re: real mode memory addressing
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
Re: real mode memory addressing
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
*** 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.
Re: real mode memory addressing
Sure, 1000h:0002h [Seg:Offset], just like you were thinking in your first post.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
*** Edited this one to... ***
Last edited by Ready4Dis on Thu Nov 19, 2009 9:13 am, edited 1 time in total.
Re: real mode memory addressing
@Ready4Dis: Have you read Neon's post correctly? He says: "assuming all numbers are decimal".Ready4Dis wrote:What are you talking about man?neon wrote: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.)GhostXoPCorp wrote:8000:1234 = 81234h? just like 8123:0004 would equal the same?
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.
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
Re: real mode memory addressing
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:
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;
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
*** 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;
Re: real mode memory addressing
Apparently I didn't . 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.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.
Appologizes, and I will edit my posts so nobody gets confused .
Re: real mode memory addressing
so i can -
1000:0000 - ffff when i get to ffff then -
2000:0000 - ffff untill i hit f000:ffff?
1000:0000 - ffff when i get to ffff then -
2000:0000 - ffff untill i hit f000:ffff?
- Love4Boobies
- Member
- Posts: 2111
- Joined: Fri Mar 07, 2008 5:36 pm
- Location: Bucharest, Romania
Re: real mode memory addressing
Argh. Just look below.
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?
Code: Select all
SSSSSSSSSSSSSSSS
OOOOOOOOOOOOOOOO
--------------------
AAAAAAAAAAAAAAAAAAAA
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 ]
[ Project UDI ]