flat assembler
Message board for the users of flat assembler.

Index > DOS > Segments

Author
Thread Post new topic Reply to topic
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 31 Dec 2011, 04:21
I could never seem to grasp the idea of segments.

I want to guess cs = address to the beginning of the code.
ds = address to beginning of data
es, no clue.

movsb requires me to put an address at si (source) to move data into an address at di.

but its ds:si to es:di

I need an explanation on all of this and how it works. Please

_________________
Oh that divide overflow. Just jumps out of the bushes every time to scare the day lights out of me.
Post 31 Dec 2011, 04:21
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 31 Dec 2011, 05:01
Ds:si is address and offset all put together.
It's like accessing an element in an array. In this case DS is the element's base address.
SI is the index/location/offset.

Here's a good example:
DS = book shelf
SI = cabinet

The same for the latter. Hope that helps
Post 31 Dec 2011, 05:01
View user's profile Send private message Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 31 Dec 2011, 05:47
Thank you. The problem was i was using movsb, when i should of been using lodsb.
Post 31 Dec 2011, 05:47
View user's profile Send private message Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 31 Dec 2011, 20:21
They both work off the same registers.
The latter one moves a byte from SI to DI. You must set the length of the bytes in CX before calling it, if you want it to handle the copying for you.

CX specifies how many times to copy bytes from the source address.
Post 31 Dec 2011, 20:21
View user's profile Send private message Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 31 Dec 2011, 21:38
I dont know how, but i added code to try and correct the segments to get movsb to work. The second i took it off the code.. it worked.

Very useful, its been forever since ive done assember (took a break and did some C++ in game development) it was actually fun, but ive found assembler to be alittle more fun, and more controlling Wink

_________________
Oh that divide overflow. Just jumps out of the bushes every time to scare the day lights out of me.
Post 31 Dec 2011, 21:38
View user's profile Send private message Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 31 Dec 2011, 22:15
Would there ever be a time when i have to set the ds and es segments myself (not being the operating system) but in a regular program
Post 31 Dec 2011, 22:15
View user's profile Send private message Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 31 Dec 2011, 22:19
i would imagine, the operating system sets the segments, and all i have to do is do lea si, var (if its not a com program) to get the offset of var in my data segment. But in flat binary (one segment) i dont have to worry about segments?
Post 31 Dec 2011, 22:19
View user's profile Send private message Reply with quote
Coty



Joined: 17 May 2010
Posts: 553
Location: ␀
Coty 31 Dec 2011, 22:39
stosb moves a byte from AX to es:di
lodsb moves a byte to AX from ds:si

Quote:
Would there ever be a time when i have to set the ds and es segments myself (not being the operating system) but in a regular program


Yes, let's say DOS loads you at 0x4000:0x0100, video memory is located at 0xA000:0x0000 (for video mode) if you want to directly draw to the display buffer (It's the fastest way) then this is how you would do it:

Code:
; Paint a white pixle on the screen...
        use16
        org     0x0100
        mov   al, 0x13    ; Set video mode '13h'
        int     0x10

        push    0xA000      ; ES == 0xA000
        pop     es
        mov     di, 0       ; DI == 0x0000
        
        mov     al, 0xFF  ; AL color = white...

        stosb               ; Right byte in al
        jmp $
    


If you don't understand WHY x86 uses segment:offset, it works like this. A 16 bit CPU can only access 64kb of RAM, so, the x86 had an extended buss, that you access the memory in 64kb chunks.
Code:
{[64kb chunk][64kb chunk][64kb chunk][64kb chunk][64kb chunk][64kb chunk]}    
ect...

es/ds lets you choose what 64kb chunk to read/right from and si/di let you choose the byte in the 64kb chunk...

Also on a side note the processor has CS:IP, this is how the cpu knows that memorychunk to exicute, and IP holds what instruction to exicute in that 64kb chink, but you need not worry about this...

_________________
http://codercat.org/


Last edited by Coty on 01 Jan 2012, 00:01; edited 1 time in total
Post 31 Dec 2011, 22:39
View user's profile Send private message Send e-mail Visit poster's website Reply with quote
typedef



Joined: 25 Jul 2010
Posts: 2909
Location: 0x77760000
typedef 31 Dec 2011, 23:04
$FFFF > sizeof(AL) Wink
Post 31 Dec 2011, 23:04
View user's profile Send private message Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 31 Dec 2011, 23:28
Thank you. A fully explained answer, with an example.


Im happy to come back and see you've gotten pretty far in this coty, anyone who works this hard to learn deserves recognition. Good job, keep it up.

_________________
Oh that divide overflow. Just jumps out of the bushes every time to scare the day lights out of me.
Post 31 Dec 2011, 23:28
View user's profile Send private message Reply with quote
Coty



Joined: 17 May 2010
Posts: 553
Location: ␀
Coty 01 Jan 2012, 00:00
Ahahaha! typedef is correct! I have fixed the example...

@GhostXoPCorp: Thanks, best of luck to you!

_________________
http://codercat.org/
Post 01 Jan 2012, 00:00
View user's profile Send private message Send e-mail Visit poster's website Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 01 Jan 2012, 00:08
Yeah 65535 > 255 Wink
Post 01 Jan 2012, 00:08
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1620
Location: Toronto, Canada
AsmGuru62 01 Jan 2012, 11:54
@GhostXoPCorp: if you use flat memory model, like:
- MS-DOS COM file
- Win32 PE file

Then you do not need to set ES,DS -- all segments are set by the OS in these cases. One small exception, however, if you allocate memory in MS-DOS (COM files can do it by resizing their own image in memory and then using INT 21H function 48H to allocate dynamically) -- in that case you DO need to set ES or DS to the segment returned by function 48H. After using the allocated memory - you need to restore the DS back to the original value given by DOS, otherwise, the global variables declared in COM file will not be accessible.
Post 01 Jan 2012, 11:54
View user's profile Send private message Send e-mail Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 01 Jan 2012, 19:22
I know, ive also taken a look at the MZ Exe format as well, this basically gave me a heads up for things to come. Thank you all for helping me understand this in all reality its the only thing i dont understand, but if i have anymore questions ill be back.

Happy new year Smile

_________________
Oh that divide overflow. Just jumps out of the bushes every time to scare the day lights out of me.
Post 01 Jan 2012, 19:22
View user's profile Send private message Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac 02 Jan 2012, 08:35
Idea A little mistake has slept in.
Coty wrote:
stosb moves a byte from AX to es:di

stosb moves a byte from AL to es:di
Quote:
lodsb moves a byte to AX from ds:si

lodsb moves a byte to AL from ds:si

Additional the Offsetaddress in DI and/or SI will be increase/decrease by 1 in correlation of the direction flag.

...

If we want to use AX = 16 bit (AH + AL):
stosw
lodsw
scasw
cmpsw
movsw

(Offset(s) will be will be increase/decrease by 2)

...

On 80386+ we can use EAX = 32 bit:
stosd
lodsd
scasd
cmpsd
movsd

(Offset(s) will be will be increase/decrease by 4.)

...

In combination with the repeat-prefix the string instruction repeats the times we have specified in the count register ((E)CX).
(Offsets will be increase/decrease in correlation of the direction flag.)

rep stosb/w/d
rep lodsb/w/d
rep scasb/w/d
rep cmpsb/w/d
rep movsb/w/d

Happy new year Very Happy

Dirk
Post 02 Jan 2012, 08:35
View user's profile Send private message Send e-mail Reply with quote
GhostXoPCorp



Joined: 13 Dec 2008
Posts: 199
Location: 01F0:0100
GhostXoPCorp 04 Jan 2012, 04:03
Thanks, but as assumed, default in my opinion is

if a byte is moved from a 16 bit (4 nibble, 2 byte blah blah) register

By default IMO means it was moved from al (the lower 8 bits, lower 2 nibbles, lower byte)

I know basically all i need to about assembler, just a bit about segments i didnt know, that i now fully understand. Thank you for your help however and happy new year to you as well! Smile

_________________
Oh that divide overflow. Just jumps out of the bushes every time to scare the day lights out of me.
Post 04 Jan 2012, 04:03
View user's profile Send private message Reply with quote
freecrac



Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac 04 Jan 2012, 09:43
GhostXoPCorp wrote:
I know basically all i need to about assembler, just a bit about segments i didnt know, that i now fully understand.

On 80386+ we can enlarge the segmentsize frrom 64 KiB up to 4 GiB.
This can be done in our GDT/LDT. Now we can access any address of 4 GiB using a pair of one Segmentregister and a 32 Bit Offsetaddress.

AsmGuru62 wrote:
...if you use flat memory model, like:
- MS-DOS COM file
- Win32 PE file

Then you do not need to set ES,DS -- all segments are set by the OS in these cases.

But if we want to set the address of the segment higher than 0 using a linear access up to 4 Gib, then we have to recalculate and decrease our Offsetaddress, so that the address (maybe to the linear frame buffer) is well pointed.

Exambple:
Code:
xor  eax, eax
mov  ax, ds
mov  edi, LFB_ADDRESS
shl  eax, 4
sub  edi, eax

xor esi, esi     ; pointed to the begin of our datasegment
mov eax, [esi]   ; get a pixelcolor from our datasegment using DS:ESI
mov [edi], eax   ; set the pixel in the upper left corner of the screen using DS:EDI
    

Dirk
Post 04 Jan 2012, 09:43
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.