greenber@timeinc.UUCP (Ross M. Greenberg) (06/18/85)
It seemed simple enough: I merely wanted to set a flag when there was a DOS call being processed. So I took over int21h and had it point to a routine called 'myint' myint: mov flag, 1 int 62h mov flag, 0 iret And it didn't work from a terminate and stay resident program, although it works in the debugger! As soon as the terminate code is run I get a whole bunch of "Insufficient disk spaces" error messages forever and ever. Time to reset. So I figured that maybe dos cares about the stack displacement (sounds reasonable, right?). okay: myint: pop [pop1] pop [pop2] pop [pop3] mov flag, 1 int 62h mov flag,0 push [pop3] push [pop2] push [pop1] iret No good --- same problem. So therefore it appears that dos is making recurssive calls to itself and cares about the current "called from" CS:IP on the stack? What is going on here? I know that I can play massive games and save dos's stack and so forth, but why should it bomb out like it does? Additionally, I made up a little terminate and stay resident piece of code for a friend of mine to give him keyclicks. I futzed with the timer to increase the sound/duration. Works like a charm on my PC --- but the timer stuff seems to have no effect on his PC-XT. What are the weirdnesses betwixt the PC and XT? And finally, what would cause a terminate and stay resident piece of code to not give its memory back to dos upon final exit? Is dos as wierd as it seems? Did Microsoft get paid by some peculiar "strangness" factor (the stranger the system, the more you get...). Or am I missing something? Mail to me, and I'll post..... -- ------------------------------------------------------------------ Ross M. Greenberg @ Time Inc, New York --------->{ihnp4 | vax135}!timeinc!greenber<--------- I highly doubt that Time Inc. they would make me their spokesperson. ------ "There's something wrong in the world. There's always been. Something no one has ever named or explained" --- Francisco d'Anconia
pda@galbp.UUCP (Paul Anderson) (06/19/85)
In article <1483> you write: >It seemed simple enough: I merely wanted to set a flag when there was >a DOS call being processed. So I took over int21h and had it point to >a routine called 'myint' > >myint: > mov flag, 1 > int 62h > mov flag, 0 > iret > >And it didn't work from a terminate and stay resident program, although >it works in the debugger! As soon as the terminate code is run I >get a whole bunch of "Insufficient disk spaces" error messages forever >and ever. Time to reset. > >So I figured that maybe dos cares about the stack displacement (sounds >reasonable, right?). okay: > >myint: > pop [pop1] > pop [pop2] > pop [pop3] > mov flag, 1 > int 62h > mov flag,0 > push [pop3] > push [pop2] > push [pop1] > iret > >------------------------------------------------------------------ >Ross M. Greenberg @ Time Inc, New York > --------->{ihnp4 | vax135}!timeinc!greenber<--------- Ross- I think that what you may find is happening is that your DS: register has not been set up to correctly address 'flag' in your data segment. If this is the case, you have two possible alternatives, as illustrated below: ---------------------------------- myint: mov cs:flag, 1 int 62h mov cs:flag, 0 iret ---------------------------------- assume cs:code, ds:data myint: push ds push ax ;save callers ds, ax mov ax,seg flag ;then resolve ds register to address 'flag' mov ds,ax mov flag,1 pop ax pop ds int 62h push ds push ax mov ax,seg flag mov ds,ax mov flag,0 pop ax pop ds iret The first case presumes that 'flag' has been declared to be within the reach of your CS: register. This is very likely, from your statement about attempting to create a terminate a stay resident program. If, however, you are using a large model program (.exe format), your DS: and CS: registers do not address the same data region and you must specifically initialize the DS: register to access your data. > No good --- same problem. So therefore it appears that dos is making > recurssive calls to itself and cares about the current "called from" > CS:IP on the stack? Your second guess about stack-specific offsets is a good point to be addressed. You were correct about the fact that PCDOS does call itself in a moderately re-entrant fashion-- but only moderately! It seems that the first 12 function calls that DOS supports does not cause DOS to activate its internal stack, but the remainder of calls to DOS will cause it to load the SP with a fixed stack address. So, DOS, for some functions will call itself if it has to print a character on the console, get a key, etc... > What is going on here? I know that I can play massive games and save > dos's stack and so forth, but why should it bomb out like it does? Hmm... interesting point to be made on stack swapping (saving dos' stack in a buffer and then calling dos again). DOS does have some static variable storage-- main case in point is the fact that DOS (although singlethreaded) maintains 'processes' for jobs running in the system. This process id is kept in static storage and changes for every program invocation, death and 'shell' command. The process id is mainly used to keep track of what job has what files open in the system. As a result, a terminate and stay resident program should not issue XENIX compatible file requests, BECAUSE it has 'terminated' as an active job. FCB requests are valid- since DOS does not track their use on a process basis (on non-network systems). > Additionally, I made up a little terminate and stay resident piece > of code for a friend of mine to give him keyclicks. I futzed with > the timer to increase the sound/duration. Works like a charm > on my PC --- but the timer stuff seems to have no effect on his > PC-XT. What are the weirdnesses betwixt the PC and XT? Don't know. > And finally, what would cause a terminate and stay resident piece > of code to not give its memory back to dos upon final exit? The DOS manual gives just a short discourse on T & SR programs- however, it is very lacking in depth. It does state that a T & SR program is 'just like COMMAND.COM' and 'becomes part of the system code'. Therefore, reading between the lines, one finds the statement: 'System code, once loaded does not exit.' And then finally on the applications side-- when the T & SR program issues a final termination (attempting to release itself as a system resource), the system only knows that the active process is terminating-- not necessarily your piece of code. So it is conceivable that you may 'kill' COMMAND.COM (or LOTUS, or BASIC, etc...). Another side note is that other jobs may have been loaded at a later time than your T & SR. Those other jobs may have inter- cepted int 21h as well- and generated a forward link in a similar fashion. To be completely terse: think what happens when you try to unlink from the middle of a chain! > Is dos as wierd as it seems? Did Microsoft get paid by some > peculiar "strangness" factor (the stranger the system, the more you > get...). Or am I missing something? Chortle. ----------------------------------------------------------------------------- Paul Anderson (akgua!galbp!pda) The opinions expressed herein do not reflect the views of "2 years, 5 mounts, and I still don't My Employer. My avocado plant understand it..." thinks otherwise.
jnw@mcnc.UUCP (John White) (06/22/85)
When a program is executed in ms-dos 2.x it is given two blocks of memory. One is the main block that starts at the begining of the 100h header and contains the program, the other is the environment block whose starting segment is given at offset 2Ch of the header. When the program terminates these two blocks are freed. If the program terminates-and-stays-resident, the environment block is not freed and the main block is shortened to the length specified by the terminate call. I have written terminate-and- stay-resident goodies that are removable. If the program is given the "remove" switch then, instead of installing itself, it looks at the interupt vector changed by a previous installation to find the address of the installed versions main block. Then the old vector is loaded from the appropriate offset in this block and the interupt vector is restored. When the program installed itself it freed up its environment pointer (using the dealloc dos call), so deallocing the main block of the installed program now removes it completely. Memory segmentation can still be a problem, so I usually remove my installed goodies in the reverse order that I installed them. This isn't important unless there is something installed that takes up a lot of memory (such as an installable ramdisk). By the way, the extra code for doing the removal is at the end of the program and is cut off by the terminate-and-stay- resident dos call so it doesn't use up memory when installed. Also, before removing the installed version, various offsets in the suposed installed version are checked to make sure the interupt vector is really pointing to an installed version. - John N. White {duke, mcnc}!jnw