/* * FreeLoader * Copyright (C) 1998-2002 Brian Palmer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ .text .code16 #define ASM #include Int386_REGS: Int386_eax: .long 0 Int386_ebx: .long 0 Int386_ecx: .long 0 Int386_edx: .long 0 Int386_esi: .long 0 Int386_edi: .long 0 Int386_ds: .word 0 Int386_es: .word 0 Int386_fs: .word 0 Int386_gs: .word 0 Int386_eflags: .long 0 Int386_vector: .long 0 Int386_regsin: .long 0 Int386_regsout: .long 0 /* * int Int386(int ivec, REGS* in, REGS* out); */ EXTERN(_Int386) .code32 /* Get the function parameters */ movl 0x04(%esp),%eax movl %eax,Int386_vector movb %al,Int386_vector_opcode movl 0x08(%esp),%eax movl %eax,Int386_regsin movl 0x0c(%esp),%eax movl %eax,Int386_regsout /* Save all registers + segment registers */ pushw %ds pushw %es pushw %fs pushw %gs pushal /* Copy the input regs to our variables */ movl $Int386_REGS,%edi movl Int386_regsin,%esi movl $0x24,%ecx rep movsb call switch_to_real .code16 /* Setup the registers */ movw %cs:Int386_ds,%ax movw %ax,%ds /* DS register */ movw %cs:Int386_es,%ax movw %ax,%es /* ES register */ movw %cs:Int386_fs,%ax movw %ax,%fs /* FS register */ movw %cs:Int386_gs,%ax movw %ax,%gs /* GS register */ movl %cs:Int386_eax,%eax /* EAX register */ movl %cs:Int386_ebx,%ebx /* EBX register */ movl %cs:Int386_ecx,%ecx /* ECX register */ movl %cs:Int386_edx,%edx /* EDX register */ movl %cs:Int386_esi,%esi /* ESI register */ movl %cs:Int386_edi,%edi /* EDI register */ /* Do not set the flags register */ /* only return its value in regsout */ //pushl Int386_eflags //popfl /* EFLAGS register */ /* Call the interrupt vector */ /*int Int386_vector*/ Int386_int_opcode: .byte 0xcd Int386_vector_opcode: .byte 0x00 /* Save the registers */ movl %eax,%cs:Int386_eax /* EAX register */ movl %ebx,%cs:Int386_ebx /* EBX register */ movl %ecx,%cs:Int386_ecx /* ECX register */ movl %edx,%cs:Int386_edx /* EDX register */ movl %esi,%cs:Int386_esi /* ESI register */ movl %edi,%cs:Int386_edi /* EDI register */ movw %ds,%ax /* DS register */ movw %ax,%cs:Int386_ds movw %es,%ax /* ES register */ movw %ax,%cs:Int386_es movw %fs,%ax /* FS register */ movw %ax,%cs:Int386_fs movw %gs,%ax /* GS register */ movw %ax,%cs:Int386_gs pushf popw %cs:Int386_eflags /* EFLAGS register */ call switch_to_prot .code32 /* Copy the variables to the output regs */ movl $Int386_REGS,%esi movl Int386_regsout,%edi movl $0x24,%ecx rep movsb /* Restore segment and all other registers */ popal popw %gs popw %fs popw %es popw %ds /* Get return value */ movl Int386_eax,%eax ret