TIP: Click on subject to list as thread! ANSI
echo: 80xxx
to: PETER LOUWEN
from: RENE HERMAN
date: 1997-12-12 11:55:00
subject: INTs in asm

Hello Peter ...
Monday December 08, you wrote to Marius Bendiksen
 MB>> * The realmode IDT is stuck (usually) at 0:0 with a limit of
 MB>>   0x3ff
 PL> "Usually" ?
Yep...
=== Cut ===
; Rene Herman, public domain, tasm lidt, tlink lidt, *will* set fire to
; your computer.
;
; Example showing validity of LIDT in real mode. Just like in protected
; mode, the real mode interrupt "descriptor" (vector) table can reside
; anywhere in the CPUs address space (that's 1MB+64k-16 in real mode),
; including the HMA (addresses 100000-10FFEF, as long as A20 is enabled,
; naturally).
;
; Although the base field of LIDT's operand is a 24bit (or 32bit, with
; an operand size prefix on a 386+) physical address, it seems it isn't
; possible to place the IDT in extended memory. The operand does get
; accepted, but the machine crashes on the first interrupt.
;
; SIDT is a non-priviliged instruction and will (therefore) return the
; protected mode IDTR when called from v86 mode. LIDT is privileged,
; so a v86 monitor may or may not emulate it (EMM386 from PC-DOS 7
; doesn't) making this stuf usefull only in "real" real mode (useless,
; that is).
_TEXT                   SEGMENT PARA    STACK
@NULL                   LABEL
ASSUME                  CS:_TEXT, DS:_TEXT
Msg                     DW MsgNope
Msg286                  DB 'This program requires a 286+$'
MsgReal                 DB 'This program requires real mode$'
MsgNope                 DB 'Nope, didn''t do anything$'
MsgOkay                 DB 'Seems to work okay$'
MsgCrLf                 DB 13, 10, '$'
; The new int 0 handler, residing (only) in the relocated IDT. Simply sets
; message to the "okay msg", showing that it got executed.
NewInt0                 PROC
        mov     cs:[Msg], OFFSET MsgOkay
        iret
NewInt0                 ENDP
main                    PROC                     ; program entry point
        push    cs
        pop     ds
        mov     dx, OFFSET MsgCrLf
        mov     ah, 009h
        int     021h
; 286 detection routine.
        mov     dx, OFFSET Msg286
        pushf                                    ; save flags
        pushf                                    ; get flags
        pop     ax
        and     ax, 00FFFh                       ; clear bits 12 to 15
        push    ax                               ; set flags
        popf
        pushf                                    ; get flags
        pop     ax
        popf                                     ; restore flags
        cmp     ax, 0F000h                       ; bits 12 to 15 set?
        je      @@Exit                           ; > y (not a 286+)
.286P   ; TASM insists on the 'P'
        mov     dx, OFFSET MsgReal
        smsw    ax                               ; smsw can't be trapped
        shr     ax, 1                            ; real mode?
        jc      @@Exit                           ; > n
        sidt    [OldIDTR]                        ; store IDTR into OldIDTR
; Calculate physical address for new one-vector IDT
        mov     ax, ds
        rol     ax, 4
        mov     dx, ax
        and     ax, 0FFF0h
        and     dx, 00Fh
        add     WORD PTR [NewIDTR.Base], ax
        adc     WORD PTR [NewIDTR.Base + WORD], dx
        cli                                      ; disable interrupts
        mov     al, 080h                         ; disable NMI
        out     070h, al
        lidt    [NewIDTR]                        ; load the new IDTR
        int     0
        lidt    [OldIDTR]                        ; restore old IDTR
        xor     al, al
        out     070h, al                         ; enable NMI
        sti                                      ; enable interrupts
        mov     dx, [Msg]
@@Exit:
        mov     ah, 009h
        int     021h
        mov     dx, OFFSET MsgCrLf
        int     021h
        mov     ax, 04C00h
        int     021h
main                    ENDP
; New interrupt vector table starts here. It seems that any byte adress in
; the "1MB+64K-16 - 4 * (highest interrupt number used + 1)" range will do
; as IDT base, although dword alignment will no doubt speed up table access.
Int0                    DD NewInt0
; LIDT/SIDT load/store from/to a 6 byte memory operand formated as:
IDTR                    STRUC
Limit                   DW ?
Base                    DD ?
IDTR                    ENDS
; The " - @NULL" just to get TASM to place a 16bit offset into a dword
NewIDTR                 IDTR { Limit = 00003h, Base = Int0 - @NULL }
OldIDTR                 IDTR ?
                        DW 00200h DUP (?)        ; stack
_TEXT                   ENDS
END                     main
=== Cut ===
Rene
---
---------------
* Origin: rene.herman@tip.nl (2:282/1.11)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.