- int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline){
- (中略)
- if (finfo != 0) {
- /* 找到了与字符串相同的文件 */
- p = (char *) memman_alloc_4k(memman, finfo->size);
- /*这里*/ *((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);
- farcall(0, 1003 * 8);
- memman_free_4k(memman, (int) p, finfo->size);
- cons_newline(cons);
- return 1;
- }
- return 0;
- }
-
- //根据输入参数打印数据 eax为当前字符 ebx为字符串 ecx长度
- void hrb_api(int edi, int esi, int ebp, int esp, int ebx, int edx, int ecx, int eax){
- /*这里*/int cs_base = *((int *) 0xfe8);
- struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
- if(edx == 1)
- cons_putchar(cons, eax&0xff, 1);
- else if(edx == 2)
- /*这里*/cons_putstr0(cons, (char*)ebx+cs_base);
- else if(edx == 3)
- /*这里*/cons_putstr1(cons, (char*)ebx+cs_base, ecx);
- return;
- }
hello3.bim : hello3.obj a_nask.obj Makefile
$(OBJ2BIM) @$(RULEFILE) out:hello3.bim map:hello3.map hello3.obj a_nask.obj
hello3.hrb : hello3.bim Makefile
$(BIM2HRB) hello3.bim hello3.hrb 0
- /* hello3.c */
- void api_putchar(int c);
-
- void HariMain(void)
- {
- api_putchar('h');
- api_putchar('e');
- api_putchar('l');
- api_putchar('l');
- api_putchar('o');
- return;
- }
-
- /* a_nask.nas */
- _api_putchar: ; void api_putchar(int c);
- MOV EDX,1
- MOV AL,[ESP+4] ; c
- INT 0x40
- RET
-
- int cmd_app(struct CONSOLE *cons, int *fat, char *cmdline){
- (中略)
- char name[18], *p, *q;
- (中略)
- 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);
- (中略)
- /*这里*/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;
- }
- return 0;
- }
- ;void start_app(int eip, int cs, int esp, int ds);
- ;操作系统栈的ESP保存在0xfe4这个地址,以便从应用程序返回操作系统时使用
- _start_app:
- PUSHAD ;将8个32位寄存器压入栈,即8*(32/8)=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 ; ESP为应用程序
- STI ; 切换完成后恢复中断请求
- PUSH ECX ; 用于far-CALL的PUSH(cs=1003*8)
- PUSH EAX ; 用于far-CALL的PUSH(eip=0)
- 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] ; 切换成操作系统ESP
- STI ; 切换完成后恢复中断请求
- POPAD ; 恢复之前保存的寄存器值
- RET
- _asm_inthandler0d:
- STI
- PUSH ES
- PUSH DS
- PUSHAD
- 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 _inthandler0d
- ADD ESP,8
- POPAD
- POP DS
- POP ES
- ADD ESP,4 ; 在INT 0x0d中需要这句
- IRETD
- .from_app:
- ; 当应用程序活动时产生中断
- CLI
- 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
- STI
- CALL _inthandler0d
- CLI
- CMP EAX,0
- JNE .kill
- POP ECX
- POP EAX
- MOV SS,AX ; 将SS恢复为应用程序用
- MOV ESP,ECX ; 将ESP恢复为应用程序用
- POPAD
- POP DS
- POP ES
- ADD ESP,4 ; INT 0x0d需要这句
- IRETD
- .kill:
- ; 将应用程序强制结束
- MOV EAX,1*8 ; 操作系统用的DS/SS
- MOV ES,AX
- MOV SS,AX
- MOV DS,AX
- MOV FS,AX
- MOV GS,AX
- MOV ESP,[0xfe4] ; 强制返回到start_app时的ESP
- STI ; 切换完成后恢复中断请求
- POPAD ; 恢复事先保存的寄存器值
- RET