From 0fd3455e42ead1a9f526a5387053998f605d8967 Mon Sep 17 00:00:00 2001 From: Yourtion Date: Wed, 4 May 2016 17:53:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=9D=E6=8A=A4=E6=93=8D=E4=BD=9C=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=EF=BC=882=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 21_day/bootpack.h | 2 +- 21_day/console.c | 7 +- 21_day/naskfunc.nas | 197 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 183 insertions(+), 23 deletions(-) diff --git a/21_day/bootpack.h b/21_day/bootpack.h index ad51fc8..a1c20ad 100644 --- a/21_day/bootpack.h +++ b/21_day/bootpack.h @@ -30,7 +30,7 @@ void asm_inthandler27(void); void asm_inthandler2c(void); unsigned int memtest_sub(unsigned int start, unsigned int end); void farjmp(int eip, int cs); -void farcall(int eip, int cs); +void start_app(int eip, int cs, int esp, int ds); void asm_hrb_api(void); /* fifo.c */ diff --git a/21_day/console.c b/21_day/console.c index bf8a05d..7cd6a79 100644 --- a/21_day/console.c +++ b/21_day/console.c @@ -257,7 +257,7 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR; struct FILEINFO *finfo; struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; - char name[18], *p; + char name[18], *p, *q; int i; /*根据命令行生成文件名*/ @@ -284,9 +284,11 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) if (finfo != 0) { /*找到文件的情况*/ p = (char *) memman_alloc_4k(memman, finfo->size); + q = (char *) memman_alloc_4k(memman, 64 * 1024); *((int *) 0xfe8) = (int) p; file_loadfile(finfo->clustno, finfo->size, p, fat, (char *) (ADR_DISKIMG + 0x003e00)); set_segmdesc(gdt + 1003, finfo->size - 1, (int) p, AR_CODE32_ER); + set_segmdesc(gdt + 1004, 64 * 1024 - 1, (int) q, AR_DATA32_RW); if (finfo->size >= 8 && strncmp(p + 4, "Hari", 4) == 0) { p[0] = 0xe8; p[1] = 0x16; @@ -295,8 +297,9 @@ int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline) p[4] = 0x00; p[5] = 0xcb; } - farcall(0, 1003 * 8); + start_app(0, 1003 * 8, 64 * 1024, 1004 * 8); memman_free_4k(memman, (int) p, finfo->size); + memman_free_4k(memman, (int) q, 64 * 1024); cons_newline(cons); return 1; } diff --git a/21_day/naskfunc.nas b/21_day/naskfunc.nas index 2feacd8..a3aecf1 100644 --- a/21_day/naskfunc.nas +++ b/21_day/naskfunc.nas @@ -16,7 +16,7 @@ GLOBAL _asm_inthandler20, _asm_inthandler21 GLOBAL _asm_inthandler27, _asm_inthandler2c GLOBAL _memtest_sub - GLOBAL _farjmp, _farcall + GLOBAL _farjmp, _start_app GLOBAL _asm_hrb_api EXTERN _inthandler20, _inthandler21 EXTERN _inthandler27, _inthandler2c @@ -116,29 +116,77 @@ _asm_inthandler20: PUSH ES PUSH DS PUSHAD - MOV EAX,ESP - PUSH EAX - MOV AX,SS - MOV DS,AX - MOV ES,AX - CALL _inthandler20 - POP EAX + MOV AX,SS + CMP AX,1*8 + JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多 + MOV EAX,ESP + PUSH SS ; 保存中断时的SS + PUSH EAX ; 保存中断时的ESP + MOV AX,SS + MOV DS,AX + MOV ES,AX + CALL _inthandler20 + ADD ESP,8 POPAD - POP DS - POP ES + POP DS + POP ES + IRETD +.from_app: +; 当应用程序活动时发生中断 + MOV EAX,1*8 + MOV DS,AX ; 先仅将DS设定为操作系统用 + MOV ECX,[0xfe4] ; 操作系统的ESP + ADD ECX,-8 + MOV [ECX+4],SS ; 保存中断时的SS + MOV [ECX],ESP ; 保存中断时的ESP + MOV SS,AX + MOV ES,AX + MOV ESP,ECX + CALL _inthandler20 + POP ECX + POP EAX + MOV SS,AX ; 将SS设回应用程序用 + MOV ESP,ECX ; 将ESP设回应用程序用 + POPAD + POP DS + POP ES IRETD _asm_inthandler21: PUSH ES PUSH DS PUSHAD + MOV AX,SS + CMP AX,1*8 + JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多 MOV EAX,ESP - PUSH EAX + PUSH SS ; 保存中断时的SS + PUSH EAX ; 保存中断时的ESP MOV AX,SS MOV DS,AX MOV ES,AX CALL _inthandler21 + ADD ESP,8 + POPAD + POP DS + POP ES + IRETD +.from_app: +; 当应用程序活动时发生中断 + MOV EAX,1*8 + MOV DS,AX ; 先仅将DS设定为操作系统用 + MOV ECX,[0xfe4] ; 操作系统的ESP + ADD ECX,-8 + MOV [ECX+4],SS ; 保存中断时的SS + MOV [ECX],ESP ; 保存中断时的ESP + MOV SS,AX + MOV ES,AX + MOV ESP,ECX + CALL _inthandler21 + POP ECX POP EAX + MOV SS,AX ; 将SS设回应用程序用 + MOV ESP,ECX ; 将ESP设回应用程序用 POPAD POP DS POP ES @@ -148,13 +196,37 @@ _asm_inthandler27: PUSH ES PUSH DS PUSHAD + MOV AX,SS + CMP AX,1*8 + JNE .from_app ; 当操作系统活动时产生中断的情况和之前差不多 MOV EAX,ESP - PUSH EAX + PUSH SS ; 保存中断时的SS + PUSH EAX ; 保存中断时的ESP MOV AX,SS MOV DS,AX MOV ES,AX CALL _inthandler27 + ADD ESP,8 + POPAD + POP DS + POP ES + IRETD +.from_app: +; 当应用程序活动时发生中断 + MOV EAX,1*8 + MOV DS,AX ; 先仅将DS设定为操作系统用 + MOV ECX,[0xfe4] ; 操作系统的ESP + ADD ECX,-8 + MOV [ECX+4],SS ; 保存中断时的SS + MOV [ECX ],ESP ; 保存中断时的ESP + MOV SS,AX + MOV ES,AX + MOV ESP,ECX + CALL _inthandler27 + POP ECX POP EAX + MOV SS,AX ; 将SS设回应用程序用 + MOV ESP,ECX ; 将ESP设回应用程序用 POPAD POP DS POP ES @@ -164,13 +236,38 @@ _asm_inthandler2c: PUSH ES PUSH DS PUSHAD + MOV AX,SS + CMP AX,1*8 + JNE .from_app +; 当操作系统活动时产生中断的情况和之前差不多 MOV EAX,ESP - PUSH EAX + PUSH SS ; 保存中断时的SS + PUSH EAX ; 保存中断时的ESP MOV AX,SS MOV DS,AX MOV ES,AX CALL _inthandler2c + ADD ESP,8 + POPAD + POP DS + POP ES + IRETD +.from_app: +; 当应用程序活动时发生中断 + MOV EAX,1*8 + MOV DS,AX ; 先仅将DS设定为操作系统用 + MOV ECX,[0xfe4] ; 操作系统的ESP + ADD ECX,-8 + MOV [ECX+4],SS ; 保存中断时的SS + MOV [ECX ],ESP ; 保存中断时的ESP + MOV SS,AX + MOV ES,AX + MOV ESP,ECX + CALL _inthandler2c + POP ECX POP EAX + MOV SS,AX ; 将SS设回应用程序用 + MOV ESP,ECX ; 将ESP设回应用程序用 POPAD POP DS POP ES @@ -213,15 +310,75 @@ _farjmp: ; void farjmp(int eip, int cs); JMP FAR [ESP+4] ; eip, cs RET -_farcall: ; void farcall(int eip, int cs); - CALL FAR [ESP+4] ; eip, cs +_start_app: ; void start_app(int eip, int cs, int esp, int ds); + PUSHAD ; 将32位寄存器的值全部保存起来 + MOV EAX,[ESP+36] ; 应用程序用EIP + MOV ECX,[ESP+40] ; 应用程序用CS + MOV EDX,[ESP+44] ; 应用程序用ESP + MOV EBX,[ESP+48] ; 应用程序用DS/SS + MOV [0xfe4],ESP ; 操作系统用ESP + CLI ; 在切换过程中禁止中断请求 + MOV ES,BX + MOV SS,BX + MOV DS,BX + MOV FS,BX + MOV GS,BX + MOV ESP,EDX + STI ; 切换完成后恢复中断请求 + PUSH ECX ; 用于far-CALL的PUSH(cs) + PUSH EAX ; 用于far-CALL的PUSH(eip) + CALL FAR [ESP] ; 调用应用程序 ; 应用程序结束后返回此处 + MOV EAX,1*8 ; 操作系统用DS/SS + CLI ; 再次进行切换,禁止中断请求 + MOV ES,AX + MOV SS,AX + MOV DS,AX + MOV FS,AX + MOV GS,AX + MOV ESP,[0xfe4] + STI ; 切换完成后恢复中断请求 + POPAD ; 恢复之前保存的寄存器值 RET _asm_hrb_api: - STI - PUSHAD ; 用于保存寄存器值的PUSH - PUSHAD ; 用于向hrb_api传值的PUSH + ; 为方便起见从开头就禁止中断请求 + PUSH DS + PUSH ES + PUSHAD ; 用于保存的PUSH + MOV EAX,1*8 + MOV DS,AX ; 先仅将DS设定为操作系统用 + MOV ECX,[0xfe4] ; 操作系统的ESP + ADD ECX,-40 + MOV [ECX+32],ESP ; 保存应用程序的ESP + MOV [ECX+36],SS ; 保存应用程序的SS + ; 将PUSHAD后的值复制到系统栈 + MOV EDX,[ESP ] + MOV EBX,[ESP+ 4] + MOV [ECX ],EDX ; 复制传递给hrb_api + MOV [ECX+ 4],EBX ; 复制传递给hrb_api + MOV EDX,[ESP+ 8] + MOV EBX,[ESP+12] + MOV [ECX+ 8],EDX ; 复制传递给hrb_api + MOV [ECX+12],EBX ; 复制传递给hrb_api + MOV EDX,[ESP+16] + MOV EBX,[ESP+20] + MOV [ECX+16],EDX ; 复制传递给hrb_api + MOV [ECX+20],EBX ; 复制传递给hrb_api + MOV EDX,[ESP+24] + MOV EBX,[ESP+28] + MOV [ECX+24],EDX ; 复制传递给hrb_api + MOV [ECX+28],EBX ; 复制传递给hrb_api + MOV ES,AX ; 将剩余的段寄存器也设为操作系统用 + MOV SS,AX + MOV ESP,ECX + STI ; 恢复中断请求 CALL _hrb_api - ADD ESP,32 + MOV ECX,[ESP+32] ; 取出应用程序的ESP + MOV EAX,[ESP+36] ; 取出应用程序的SS + CLI + MOV SS,AX + MOV ESP,ECX POPAD - IRETD + POP ES + POP DS + IRETD ; 这个命令会自动执行STI