cpu 8086 org 0x7C00 stack: equ 0x7C00 framsz: equ 0x300 jmp init ; Data on user stack while in kernel (5 words): ; AX BP IP CS flags ; Kernel stack: ; [frame] SP SS ; BP-^ ; The start of the frame is available via BP. ; The frame is followed by a long ptr to the user stack. ; Main entry point int20h: xor ah, ah int21h: push bp push ax ; Test if SS=0, if it is, we assume we are already on kernel stack mov ax, ss test ax, ax jz rentry ; Save user stack mov ax, ss mov [stack-2], ax mov [stack-4], sp ; Set up kernel stack xor ax, ax mov ss, ax mov sp, (stack-4) jmp scall ; This is like the above, except that it doesnt switch stacks. ; The 'user' stack data is after (below on stack) the kernel frame. ; [frame] SP SS AX BP IP CS flags ; \-\--^ rentry: mov ax, sp push ss push ax scall: sub sp, framsz mov bp, sp call getax int 3 ; Restore user stack mov sp, [bp+framsz] mov ax, [bp+framsz+2] mov ss, ax pop ax pop bp iret ; Get AX from the user stack getax: push ds push si lds si, [bp+framsz] lodsw pop ds pop si ret sftab: dw 0, 0, 0, 0 ; 00-03 dw 0, 0, 0, 0 ; 04-07 dw 0, 0, 0, 0 ; 08-0b dw 0, 0, 0, 0 ; 0c-0f dw 0, 0, 0, 0 ; 10-13 dw 0, 0, 0, 0 ; 14-17 dw 0, 0, 0, 0 ; 18-1b dw 0, 0, 0, 0 ; 1c-1f dw 0, 0, 0, 0 ; 20-23 dw 0, dos25, 0, 0 ; 24-27 dw 0, 0, 0, 0 ; 28-2b dw 0, 0, 0, 0 ; 2c-2f ; DOSINT 25h: Set interrupt vector ; IN al interrupt number ; ds:dx entry point dos25: ret ; ===== end of resident, begin of transient startup code init: xor ax, ax mov ds, ax mov es, ax mov ax, 0x1000 mov ss, ax xor sp, sp mov ax, 0x2521 mov dx, int21h pushf push cs call int21h mov ax, 0x2520 mov dx, int20h pushf push cs call int21h main: push cs pop ds mov si, msg mov ah, 0x0e xor bx, bx loop: lodsb test al, al jz end int 0x10 jmp loop end: hlt jmp end align 2048 msg: db "rdos kernel stub", 0x0A, 0x0D, 0