30天自制操作系统——第二十一天用C语言编写应用程序

本文介绍了在自制操作系统中如何用C语言编写应用程序,包括处理栈异常以发现bug,强制结束应用程序,显示字符串,创建窗口以及在窗口中描绘字符和方块。通过实例代码展示了如何实现这些功能,并提供了相应的中断处理和内存管理的细节。
摘要由CSDN通过智能技术生成

帮助发现bug

CPU的异常处理功能,还能帮助我们发现bug,比如下面的例子:

bug1.c:

void api_putchar(int c);
void api_end(void);

void HariMain(void)
{
   
	char a[100];
	a[10] = 'A';		/* 这句没有问题 */
	api_putchar(a[10]);
	a[102] = 'B';		/* 这句有问题 */
	api_putchar(a[102]);
	a[123] = 'C';		/* 这句也有问题 */
	api_putchar(a[123]);
	api_end();
}

由于数组保存在栈中,数组越界会产生栈异常。我们编写一个函数来处理栈异常,栈异常的中断号为0x0c。CPU说明书中,从0x00到0x1都是异常所使用的中断。IRQ的中断号都是从0x20之后开始的,其中0x00号是除零异常,当试图除以0时产生;0x06号是非法指令异常,当试图执行CPU无法理解的机器语言指令时产生。

naskfunc.nas

_asm_inthandler0c:
		STI
		PUSH	ES
		PUSH	DS
		PUSHAD
		MOV		EAX,ESP
		PUSH	EAX
		MOV		AX,SS
		MOV		DS,AX
		MOV		ES,AX
		CALL	_inthandler0c
		CMP		EAX,0
		JNE		end_app
		POP		EAX
		POPAD
		POP		DS
		POP		ES
		ADD		ESP,4			; 在INT 0x0c 中也需要这句
		IRETD

发生异常时,应该能显示引发异常的指令地址,我们在console.c程序中加上这个功能。

console.c节选:

int *inthandler0c(int *esp)
{
   
	struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
	struct TASK *task = task_now();
	char s[30];
	cons_putstr0(cons, "\nINT 0C :\n Stack Exception.\n");
	sprintf(s, "EIP = %08X\n", esp[11]);
	cons_putstr0(cons, s);
	return &(task->tss.esp0);	/* 强制结束程序 */
}

int *inthandler0d(int *esp)
{
   
	struct CONSOLE *cons = (struct CONSOLE *) *((int *) 0x0fec);
	struct TASK *task = 
  • 22
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值