[fpc-devel]Calling previous INTroutine
startx
startx at geocities.com
Mon Dec 18 15:39:49 CET 2000
Aleksey V. Vaneev wrote:
> Okay. I've tried to use ds_alias.. Somebody said me it is a right way of
> restoring selectors.
I do not know anything about ds_alias, but for it to work there are two
requirements to be satisfied:
1) It should reside in the CS segment, and the compiler should remember
about that, as you declare it as
var
ds_alias: Word; external name '___v2prt0_ds_alias';
... and you refer to it with
mov ax, cs:[ds_alias]
I think, however, this is true, as would be no reason to declare such
a variable with another thing in mind. If it is declared in the DS
segment, you can't access it without having DS correctly set up.
2) This variable should be already locked, as you don't lock it.
I've just tried this ds_alias, and it seems to me that ds_alias resides
in DS segment itself. So, you can't use it from an interrupt procedure
if you don't lock it; moreover, you can't access it without having DS
correctly set up.
When using this mechanism, you have no need to use "procedure dsdummy",
as you don't even refer it, and so you don't have to use the small
assembler routine to set up dsdummy:
> {asm
> mov ax, ds
> mov ebx, offset dsdummy
> mov cs:[ebx], ax
> end;} // this part traps on "mov ax, ds"
About this fragment, which uses CS as imposition: this is the first
thing I tried some time ago. And, yes, this caused an error. This is
strange, because in the FPC documentation it is stated that "the code
segment is writeable by default".
Apart from that, the error you should receive is on "mov cs:[ebx],ax",
because there cannot be any error on "mov ax,ds"; this could be some
strange thing from your debugger (don't trust any). I verified it just
now using gdbpas.
Jonas Maebe wrote:
> I just looked again at this and this is wrong: this should be
> mov word ptr cs:[ebx],ax
Writing "word ptr" is not required, as the AX register is a 16 bit
register. And it does not work because it raise a SIGABORT error. I
remember that, some time ago, I tried also to set write privileges in
the code segment, but the only way to get the work done was to use "mov
[ebx],ax".
Anyway, this is your program working after some adjustment:
Assured to work.
Cheers.
-------------- next part --------------
uses Go32;
{$asmmode intel}
const
TimerIRQVector = 8;
var
OldIRQHandler: TSegInfo;
ds_alias: Word; external name '___v2prt0_ds_alias';
procedure dsdummy; assembler;
asm
dw 0
end;
procedure TimerIRQHandler; assembler;
asm
pushad
push es
push ds
push fs
push gs
mov ebx,offset dsdummy
mov ax,cs:[ebx]
mov ds, ax
mov es, ax
pushfd
lcall [OldIRQHandler]
pop gs
pop fs
pop ds
pop es
popad
iret
end;
function setNewIRQHandler: Boolean;
var
HandlerAddress: TSegInfo;
begin
HandlerAddress.segment := get_cs;
HandlerAddress.offset := @TimerIRQHandler;
SetNewIrqHandler := set_pm_interrupt (TimerIRQVector, HandlerAddress);
end;
procedure lockVariables;
begin
lock_data (OldIRQHandler, SizeOf (OldIRQHandler));
lock_code (@dsdummy, 400);
end;
procedure unlockVariables;
begin
unlock_data (OldIRQHandler, SizeOf (OldIRQHandler));
unlock_code (@TimerIRQHandler, 400);
end;
var
SaveExitProc: Pointer;
procedure TimerSafeExit;
begin
ExitProc := SaveExitProc;
set_pm_interrupt (TimerIRQVector, OldIRQHandler);
unlockVariables;
end;
var
prova : word;
begin
if (not get_pm_interrupt (TimerIRQVector, OldIRQHandler)) then
halt;
lockVariables;
asm
mov ax, ds
mov ebx, offset dsdummy
mov [ebx], ax
end; // this part traps on "mov ax, ds"
if (not setNewIRQHandler) then
begin
unlockVariables;
halt;
end;
SaveExitProc := ExitProc;
ExitProc := @TimerSafeExit;
writeln('now timer is ',memw[$40:$6c]);
ReadLn;
writeln('and now it is ',memw[$40:$6c]);
end.
More information about the fpc-devel
mailing list