Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

indirect far jmp - calling old INT problem (Developers)

posted by bretjohn Homepage E-mail, Rio Rancho, NM, 14.05.2012, 18:30

FWIW, these days (I didn't used to do this) most of my ISR's start as follows:

PUSH BP
MOV BP,SP
PUSHF
STI
CLD
...

At least in theory, the only difference between the flags at [BP+6] (what will be returned to the caller) and at [BP-2] (the flags I'm working with at the start of my code) will potentially be IF and TF. However, this is only guaranteed to be the case if I'm the first ISR in the chain and the CPU is the one providing the stack and flag and register input. If I'm not first, then that may not be the case unless all of the ISR's further up the chain all did things "correctly".

Unless a particular INT sub-function uses one of the flags as an input parameter (rare, but does happen, like INT 15.4F, and should never happen in an IRQ handler), making sure the input flags to the next ISR are the same ones that you got isn't necessarily a big deal, since it can test the flags on the stack (at [BP+6]) instead of just doing an immediate JC/JNC (or whatever). But, it is important that you do not simply CALL the old ISR like this, unless you're 100% sure your flags haven't changed since the start of your ISR handler:

PUSHF
CALL CS:[OldVector]

In most of my ISR's, if I need to call the old ISR, that's the first thing I do, so I haven't messed with any flags yet and it's not a problem. If this isn't the case for you, though, at an absolute minimum, you should do a "PUSH [BP+6]" instead of a "PUSHF" here (or something similar). It is also important that you do this for all interrupts, not just the ones where you think/know it may matter (like INT 15h), since there can be extensions and overloads and other things you don't know about. You should "emulate" exactly the same thing the CPU does. I think this may be a major cause over the years of TSR's needing to get installed in a particular order for unknown reasons.

If I JMP to the old ISR, I do this, guaranteeing that the old ISR gets the same input flags that I did:

...
POPF
POP BP
JMP CS:[OldVector]

If I need to return CF as a parameter, I do one or the other of the following as appropriate, guaranteeing that CF is the only modified flag:

OR B [BP+6],1 ;Set return CF
AND B [BP+6],(NOT 1) ;Clear return CF

Obviously, some of the details need to be modified to some degree if [OldVector] isn't stored in your own memory, or if you need to CALL the old ISR at the middle/end of your ISR instead of the beginning, or ...

To make code that is "correct", it's not always possible to make it as small as you would like it to be.


Also FWIW, not all assemblers will just automatically insert the SS: override OpCode if you do something like this:

OR B SS:[BP+6],1

Some are "smart enough" to know that the SS: override isn't needed, and some aren't. My assembler does not insert them, so in my code I put the SS: in there as a form of documentation, to remind myself that I'm working with the stack and not "regular" memory.

 

Complete thread:

Back to the forum
Board view  Mix view
22762 Postings in 2122 Threads, 402 registered users (0 online)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum