Page 1 of 1
need some segment information
Posted: Fri Jul 08, 2005 11:00 pm
by earlz
ok well i know what a segment is and such but i have no idea what the segment should be like the steps like if your program is loaded at segment 0000(for example) and u fill up the 64k limit and u switch the segment to 0001 exactly what does that do does that give you one more byte or 64k more bytes
Re: need some segment information
Posted: Sat Jul 09, 2005 11:00 pm
by ezanahka
Converting between linear and real mode addresses goes like this (at least I think it goes like this...
Linear addresses are 32 bits and map directly into memory.
f.ex. 0x00100000 is 1 MB
Real mode segmented addresses are converted into 20 bit linear addresses.
The 20 bit linear address comes from (segment * 0x10) + (offset)
So logically...
0x0000:0000 = segment: 0x0 offset: 0x0
(0x0*0x10)+(0x0) = 0x0
0x0001:0000 = segment: 0x1 offset: 0x0
(0x1*0x10)+(0x0) = 0x10
0x4000:0x123 = (0x4000*0x10)+(0x123)=0x40123
A more visual approach based on the fact of overlapping of segment and offset. The offset represents bits 0-15 and the segment represents bits 4-19 of the linear address. The linear address is the sum of the segment and the offset.
0xF000:0x1
is
0xF000
+0x0001
---------
0xF0001
0xFFFF:0x10
is
0xFFFF
+0x0010
----------
0x100000 or 0 (Depending on the status of A20. If A20 is disabled it wraps around to 0.)
If you switch the segment base from 0x0000 to 0x1000 then you move into the next 64kB.
If you switch it from 0x0000 to 0x0001 then the area you can reference moves up 16 bytes from (0B to 64kB) to (16B to 64kB+16B).
Well... at least I think it goes like this.
Re: need some segment information
Posted: Sat Jul 09, 2005 11:00 pm
by earlz
Thanks for the explanation i didnt quite get the last part but the visual part is what was real simple to understand and was basically all i needed to know
Re: need some segment information
Posted: Sat Jul 09, 2005 11:00 pm
by yetAnotherOS
I read the thread and thought that there was one more thing you might like to know. I had just the same problem with real mode segments and then worked it all out. When working with real mode segments, there are many ways to address the same memory location. Let us examine one situation: (all numbers are in hex)
To access fffff you could use:
f000:0fff
ff00:00ff
fff0:000f
and really any combination that adds up to the correct address.
It your original post you asked:
your program is loaded at segment 0000(for example) and u fill up the 64k limit and u switch the segment to 0001 exactly what does that do does that give you one more byte or 64k more bytes
To give a very quick answer, you've only given yourself 16 more bytes. You've gone from the linear address 0x00000 to the address 0x00010.
I hope this helps.[/quote]
Re: need some segment information
Posted: Sat Jul 09, 2005 11:00 pm
by earlz
hmm thanks
even though i cant quite put ti to use i can be thinking about how it will work
Re: need some segment information
Posted: Sat Jul 09, 2005 11:00 pm
by dave
yetAnotherOS wrote:
To access fffff you could use:
f000:0fff
ff00:00ff
fff0:000f
and really any combination that adds up to the correct address.
.
The above is actually incorrect those are all different addresses ( probably just a typo ).
Firstly, the reason for segments has to do with being in 16 bit mode. Since registers are only 16 bits you could only represent 2^16 addresses which happens to be 65535 ( or what we like to call 64K ). As you can see with only one register used for addressing we could never address any more memory than 64k. So to get access to a megabyte we need 2^20 bits which is 1,048,576 ( or one meg ). To solve this problem segementation was inventeds which allows the upper 4 bits of an address to be stored in the upper nibble ( 4 bits ) of one register ( one of the segment registers es, ss, ds, etc. ) and the lower 16 bits to be stored in another register, mem location, etc. So to convert the information back to a linear address the segment value is shifted to the left 4 bits ( or multiplied by 16 ) and the lower 16 bits are added to the shifted value ( as others have shown above ).
In C the actual process would look like
( segment << 4 ) + offset
As an example:
0xF000:0x000F (segment:offset) would be F000F
Now to correct the above example of two things leading to the same address. Since the cpu does not change any of the segment data when it shifts it you can put any value you want as the segement which gives the possibility of having to segment:offset combinations leading to the same linear address. For example
0xFF00:0x00FF
0xFF0F:0x000F
both point to 0xFF0FF
Most of the reason for segmenting is in the history of processors and memory requirements of the time when they were developed. You have to remember nobody ever expected people to be using 64k of memory let alone a megabyte.
Dave