X-Authentication-Warning: delorie.com: mailnull set sender to djgpp-bounces using -f From: "MarKol" Newsgroups: comp.os.msdos.djgpp Subject: Re: DS and ESP Date: Thu, 21 Feb 2002 21:25:51 +0100 Organization: tp.internet - http://www.tpi.pl/ Lines: 228 Message-ID: References: <968-Mon18Feb2002212153+0200-eliz AT is DOT elta DOT co DOT il> NNTP-Posting-Host: seazone.gda.pl Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 8bit X-Trace: news.tpi.pl 1014382429 14102 195.117.175.253 (22 Feb 2002 12:53:49 GMT) X-Complaints-To: usenet AT tpi DOT pl NNTP-Posting-Date: Fri, 22 Feb 2002 12:53:49 +0000 (UTC) X-Priority: 3 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MSMail-Priority: Normal To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Hi : Użytkownik "Eli Zaretskii" napisał w wiadomości : > : > +I wonder if gcc, doesn't change ds? : : Code generated by GCC assumes DS = SS = ES. : : > I think that there no need to change to change ds for compiler but : > I'm not sure about this. : > +Are DJGPP's libc function conform to his rule? : > In other words I wonder in there is some piece of code in DJGPP's libc : > which may be executed during normal program flow (not loading : > or ending), and changes ds selector (and it is possible : > to accept HW interrupt by CPU at ehis moment)? : : DS may become invalid if a signal happens, like if you press Ctrl-C : or run with timers. The library provides a special alias selector, : __djgpp_ds_alias, which is always valid and spans the same memory : region as the selector normally loaded into DS. Yes, but how do I load this __djgpp_ds_alias selector when my ds is invalid?? But I think this will work and I'm able to load proper ds segment in my wrapper routine. I can put something like this in my wrapper: . . . mov ax, 0 mov ds, ax . . . When program is running I can get my ds segment selector (_my_ds() AFAIR) and then modify code shown above (via DS, since DS=SS=CS), replacing zero with proper data segment selector returned by _my_ds(). I think this will definitely solve problems with valid ds segment when my interrupt wrapper is called. : : > b) similar problem is about esp (I belive that ss is valid ). : > My stub routine assumes that valid program data on stack are : > pointed by esp and higher values. : : The interrupt handler is called on a special locked stack provided by : the DPMI host. Is this the stack you are talking about? If so, it : will never clash with the application's stack. : No, I'm talking about user's stack. I create alias descriptor for user's stack (with changed DPL to 0, since I cannot reload ss (when executing on ring0) with selector pointing to ring 3 descriptor). I'm doing this because I want to satisfy GCC about CS=DS=SS. 0. I assume that no page fault occurs (all required pages are present). (this can be easily achieved, under CWSDPMI and plain DOS) 1. I put my interrupt gate directly in IDT and DPMI host doesn't have chance to catch such interrupt. 2. I case when ring is changed selector and stack pointer is taken from TSS, and this is internal CWSDPMI stack. 3. In the begining of my interrupt wrapper stack looks like this (when ring switch occurs) |--------| [esp+16] | SS | ; ring 3 ss |--------| [esp+12] | ESP | ; ring 3 esp |--------| [esp+8] | EFLAGS | ; |--------| [esp+4] | CS | ; |--------| [esp] | EIP | ; |--------| | | 4. Oh no, my english is poor. Maybe I'll show code which is doing what I'm writing of. This is unmodified version (assumes that ds is proper) but seems to work fine. I'll implement trick with changing ds as written above. asm_int_wrapper: pushad push ds push es ; ; ; mov ax, cs mov ecx, [esp+4+40] xor ax, cx and ax, 0x3 jz .@ring_not_changed ; ; ring changed ; mov eax, [esp+16+40] ; user's stack selector mov edi, [esp+12+40] ; user's stack pointer mov es, ax xor eax, eax mov ax, ss ; ; Here is important that there is no user's data on stack below ; esp! ; write our current ss:esp on user's stack ; mov [es:edi-4], eax mov [es:edi-8], esp ; ; switch to user's stack ; mov edx, [esp+12+40] mov eax, [stack_r0selector] push eax sub edx, 8 ; lower stack pointer since ; there is stored our ss:esp push edx lss esp, [esp] ; ; stack switched ; ; ; load user's service routine address ; mov eax, [user_c_routine00] ; ; execute user's routine (may be written completely in C, because DS=SS=CS) ; call eax ; ; switch back to DPMI stack ; lss esp, [esp] jmp .@int_exit_code .@ring_not_changed: mov eax, [user_c_routine00] call eax .@int_exit_code: ; ; send EOI to 8259A ; mov al, 0x0B out 0xA0, al in al, 0xA0 test al, 0xff jz .@eoi2master_only mov al, 0x20 out 0xA0, al .@eoi2master_only: mov al, 0x20 out 0x20, al pop es pop ds popad iretd Of course I can allocate some space in my data segment and use this allocated buffer as the user stack when C service routine is called (CS=DS=SS would be satisfied) but using existing user stack looks more elegant ;-). So if somebody is sure that esp is always valid please, let me know about it. : > Anything below esp is not : > important for the program. But I've seen codes like this : > (simple but ilustrates problem accessing stack segment below esp, : > maybe programmer thought that nothing wrong can happen): : > : > mov [esp-4], eax : > shl eax, cl : > add [edi], eax : > mov eax, [esp-4] : > : > If HW interrupt will be accepted between eax is restored there : > are valid program data on the stack below esp. My asm stub uses : > user stack below esp, and assumes there is no valid : > user data below esp (it uses 8 bytes for ss and esp) : : It is IMHO a very bad idea for the interrupt handler to use the : application stack. Especially since the selector loaded into SS can : become invalid exactly like DS. Maybe you're right, but: I'd like to write service routines in C. You said that GCC assumes CS=DS=SS, so how can I write my routine in C when I'm operating on stack provided by DPMI?? Best regards, -- / |_|_|_|_| void identification(){ \ / |mov e| printf(" Marek Kolacz "); \ || |cld | printf(" markol4 AT wp DOT pl "); || \ |movsd| } / \_____/_______\__________________________________________/