The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Mark Jones on April 12, 2005, 07:17:21 PM

Title: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: Mark Jones on April 12, 2005, 07:17:21 PM
I recall trying to use these awhile back (when I was a NOOB noob) but only got various errors. Recently I debugged a sample .dll and saw where FS had data in it. Can these registers be used in typical MASM32 applications, or only in real-mode?  Thanks. :)
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: QvasiModo on April 12, 2005, 11:07:54 PM
In theory user-mode apps are not supposed to touch the segment registers. But FS in particular can be used to access some OS-specific kernel structures, and that can be an useful "hack".
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: hutch-- on April 13, 2005, 12:04:24 AM
Mark,

The specification of 32 bit FLAT memory model in Windows is to set the normal segment registers to the same address.

In order,

CS = Code segment
DS = Data segment
ES = Extra segment
SS = Stack Segment

The last 2 FS and GS are not used in the specification but are used at times by the OS for structured exception handling so while you can use them occasionally, its risky depending on the OS ersion you use as they may be in use for something else.

Placing the normal segment registers at the same address is what makes FLAT memory model possible so that you have both DATA and CODE written in the same memory space which is standard with a PE file.
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: tenkey on April 13, 2005, 02:50:02 AM
You cannot use the segment registers as general purpose registers because 32-bit code can only run in protected mode. All segment registers must be either NULL or have a valid selector.

The FS register is used to point to thread-specific information. This includes stack limits, the exception handler chain, handles to thread local storage, and probably handles to message queues.
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: Mark Jones on April 13, 2005, 05:22:17 PM
 Ok then as a hack, it should be possible to:

1. push FS onto the stack
2. use FS in a local routine
3. pop FS?

GS does not like this at all... access violation.

Strange, MOV FS,EAX does not give an error. It compiles to MOV FS,AX however.

Also is it possible to use the debug registers DR0-7 for anything in Win32?
MOV DR0,EAX  yields a "privledged command" error.

Thanks for the great tips. :bg
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: pbrennick on April 13, 2005, 07:36:44 PM
Mark,
I think your tests have already told you what you need to know.  I have seen people use FS in there code.  Personally, I have programmed for years and never played with the stuff like that.  I am sure you just want to know all there is to know and I respect that a lot.  Have fun and above all, be careful.  I would recommend you do a cold boot any time you get a crash using some of this stuff.  OS recovery is never guarranteed to be totally effective.  You could wind up running a hybrid of your own OS and not know it and the results of that may lead to more errors in other programs that ordinarily would run with no errors.  I have a 500 mhz K6 that I use for testing.  Think about something like that.

Paul
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: QvasiModo on April 13, 2005, 09:24:05 PM
Quote from: Mark Jones on April 13, 2005, 05:22:17 PM
Ok then as a hack, it should be possible to:

1. push FS onto the stack
2. use FS in a local routine
3. pop FS?

GS does not like this at all... access violation.
Typically you use FS to access OS specific structures beginning at FS:[00000000h]. I don't know what GS is used for though.
QuoteStrange, MOV FS,EAX does not give an error. It compiles to MOV FS,AX however.
That's because segment registers are only 16 bits in size. :)

BTW, I found this on the old forum:
http://old.masmforum.com/viewtopic.php?t=4810&highlight=&sid=8d3110e9f3698fce4784f9a468ebf0b7
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: rea on April 13, 2005, 10:27:50 PM
Searching a little on the web for: seh exception handling fs debug

http://www.assembly-journal.com//viewarticle.php?id=69
http://www.jorgon.freeserve.co.uk/Except/Except.htm

http://www.microsoft.com/msj/0197/Exception/Exception.aspx
http://msdn.microsoft.com/msdnmag/issues/02/03/hood/default.aspx


You can find many other ones :).
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: tenkey on April 14, 2005, 03:44:36 AM
Quote from: Mark Jones on April 13, 2005, 05:22:17 PM
Ok then as a hack, it should be possible to:

1. push FS onto the stack
2. use FS in a local routine
3. pop FS?

GS does not like this at all... access violation.

If GS does not like your value, FS won't either. You can put any value in the extra segment registers if you run from a DOS executable, but not from a Win32 (PE) executable.
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: roticv on April 14, 2005, 01:10:50 PM
Why do you have to resort to using segment registers? Isn't sse/mmx/general purpose registers enough for your uses?
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: Mark Jones on April 14, 2005, 02:40:51 PM
Quoteroticv: Why do you have to resort to using segment registers? Isn't sse/mmx/general purpose registers enough for your uses?

Can SSE/MMX regs hold arbitrary data? That would be great, haven't gotten into math yet.

Recently I made a small app to intelligently convert spaces <--> tabs in source documents. The routine used EAX,EBX,ECX, and EDX as two string pointers, three counters, and two byte buffers. Probably a lot of room for optimization, but hey I am a noob at this. :) The app works, but I almost ran out of registers. Now what could I do if I needed another register or two? Values could be pushed and poped from the stack, but that's going to be much slower than using any register. It seems like a good idea to define the limits of what can actually be done with x86. :)

rea and tenkey, aaaah the SEH uses FS as a pointer, that makes sense. So if an exception occurs during a routine which uses FS, (and it doesn't point to any record) Windows might decide to go belly-up? :bg

QuoteMJ: Strange, MOV FS,EAX does not give an error. It compiles to MOV FS,AX however.
QuoteQvasiModo: That's because segment registers are only 16 bits in size. :)

Hmm, yes of course, but shouldn't it give an incompatible size error? EAX=32 bits, FS=16 bits.
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: pbrennick on April 14, 2005, 03:16:30 PM
Mark,
About the assembler changing your source so it could compile (eax --> ax), there is no question that this is very heavy handed functionality.  I don't remember that I ever experienced such a thing, myself.  I do know that I don't care for it.  I would not be surprised if this is not a soft bug in the assembler (a fix put in by a lazy developer).  Surprising to see this later in the game.  You will probably never know why because know one will ever acknowledge it (at Microsoft).  It is a pretty rock solid assembler, though, all things considered.
Paul
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: roticv on April 14, 2005, 04:56:54 PM
Read the caution by tenkey. Segment registers are not general purpose registers.

Well I think if you really run out of general purpose registers, you have to end up using memory/stack. Of course you can temporary store the value of esp in mmx register which allows you to have esp as another register. For example


movd mm0, esp
;...
movd esp, mm0
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: Mark_Larson on April 14, 2005, 06:57:15 PM
Quote from: roticv on April 14, 2005, 04:56:54 PM
Read the caution by tenkey. Segment registers are not general purpose registers.

Well I think if you really run out of general purpose registers, you have to end up using memory/stack. Of course you can temporary store the value of esp in mmx register which allows you to have esp as another register. For example


movd mm0, esp
;...
movd esp, mm0


  You can also expand on this and use MMX registers as temporary registers to hold general purpose registers.  I recommend pushing/popping on the stack, but this works to.


movd  mm0, eax               ;save eax in mm0
mov   eax,[mem_locaotion] ;get new eax value from memory
... perform operations on eax
movd eax,mm0                ;restore original value for eax


  In addition you can look at the size of your variables.  Is your loop counter less than 256?  You can use byte registers.  Using ROLs ( or BSWAPs) you can get 4 8 byte registers out of EAX.  I've used that trick to get more registers.  Works for 16 byte values as well.  As long as you aren't going to be using a full 32-bit value, you can avoid using a full 32-bit register, and thus increase the number of registers you have.


  I would never use segment registers as temporary registers.  You're asking for a problem. 
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: dsouza123 on April 15, 2005, 02:40:11 AM
In addition to  EAX, EBX, ECX, EDX there are also EDI and ESI
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: Mark Jones on April 15, 2005, 04:55:10 AM
dsouza123, is there any stipulations regarding the use of EDI and ESI? I guess ESP/EBP could be utilized also, with a lot of trickery. I was under the assumption that EDI and ESI were also reserved for some purpose? It's hard being a noob. :toothy
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: hutch-- on April 15, 2005, 05:22:24 AM
Mark,

In Windows you are required to preserve EBX ESI EDI ESP and EBP so you can make a mess of EAX ECX and EDX. Now the catch is the other way is that if you are using any of EAX ECX or EDX you must preserve them if you call a procedure that works according to the Windows convention.
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: MazeGen on April 15, 2005, 07:41:57 AM
Quote from: Mark Jones on April 13, 2005, 05:22:17 PM
Ok then as a hack, it should be possible to:

1. push FS onto the stack
2. use FS in a local routine
3. pop FS?

GS does not like this at all... access violation.

You can't use segment register as general-purpose register in windows, beause it contains index to some tabels with segment descriptors.
It seems that GS in all versions of windows contains NULL selector, what means it is unused. Anyway, value of GS is oficially reserved and you shouldn't depend on the value. But if you like playing with it, you can fill it with values 0, 1, 2, 3 without any problems (it still means NULL selector).

Quote from: Mark Jones on April 13, 2005, 05:22:17 PMStrange, MOV FS,EAX does not give an error. It compiles to MOV FS,AX however.

That's special case. From the Intel instruction set reference:
Quote
When the processor executes the instruction with a 32-bit general-purpose register, it assumes that the 16 least-significant bits of the general-purpose register are the destination or source operand.
In fact, such instruction really compile to MOV FS,EAX in MASM, but most of dissemblers and debuggers (like OllyDbg) shows it like MOV FS,AX, probably because it doesn't want to confuse the users with different operand sizes. You can distinguish between EAX and AX in the instruction according to whether the first byte of the opcode is 66h (operand-size prefix) or not.

Quote from: Mark Jones on April 13, 2005, 05:22:17 PMAlso is it possible to use the debug registers DR0-7 for anything in Win32?
MOV DR0,EAX  yields a "privledged command" error.
You normally can't in user mode (ring3). But you can fill them in windows via structured exception handler. See CONTEXT structure.
Title: Re: Can CS,DS,ES,FS,GS, and SS be used in Win32?
Post by: AeroASM on April 16, 2005, 01:19:32 PM
In protected mode you will get an error if you put a value into a segment register that does not point to a valid selector in the GDT (or LDT??). I painfully found this out after spending weeks working out that my OS kept triple-faulting because I put 16h, not 16.