need some segment information

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.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

need some segment information

Post 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
Last edited by earlz on Fri Jul 08, 2005 11:00 pm, edited 1 time in total.
ezanahka
Posts: 10
Joined: Tue Jun 28, 2005 11:00 pm
Location: Rovaniemi, Lapland, Finland
Contact:

Re: need some segment information

Post 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.
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: need some segment information

Post 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
yetAnotherOS
Posts: 12
Joined: Fri Jul 01, 2005 11:00 pm

Re: need some segment information

Post 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]
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Re: need some segment information

Post by earlz »

hmm thanks

even though i cant quite put ti to use i can be thinking about how it will work
dave
Member
Member
Posts: 42
Joined: Sat Jul 09, 2005 11:00 pm

Re: need some segment information

Post 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
Post Reply