【自制操作系统】以《30天自制操作系统》的03day为基础,脱离繁杂的GUI,做一个工作在文本模式下的命令行操作系统(1)----print函数

自制操作系统(一、环境配置一个操作系统 这个系列用于自制操作系统,不会太长,但是功能应有尽有作者是准备升初一的学生,但是五年级就自学了微积分,复变函数等其他的教程书籍的环境配置总是出问题,要么就是Linux,要么就是32位电脑,对Windows64x用户非常不友好,我的教程适用于任何电脑其他的教程书籍要么要深厚的计算机底层基础,要么就像haribote(《30自制操作系统》)一样只有外部工作 阅读详情

 当你学习到03day时 说明你已经进入到了保护模式下 并且使用了C语言进行了开发

由于我们是要在文本模式进行开发 所以请先让显卡进入文本模式,而不是图形模式

然后清空 harimain的所有代码 正式开始我们的开发

首先我们得让光标动起来 不可能让我们自己画一个光标吧 而这个只能用汇编语言实现 我们别无选择

_ASM_call:  ;移动光标
mov dx,03d4h;03d4h是索引端口
mov al,0eh;内部的0eh位置存放着光标位置的高八位
out dx,al
inc dx;03d5h是数据端口用于读写数据
in al,dx;读取光标的高八位并且放入bh
mov bh,al
 
dec dx;这儿开始读取光标位置的低八位放入bl
mov al,0fh;0fh位置存放着光标位置的低八位
out  dx,al
inc dx
in al,dx
mov bl,al
 

mov word bx,[esp+4]   ;获取参数中的光标位置
 
mov  dx,03d4h;这段代码将改变后的光标位置写入端口内相应的地方以便下次访问
mov al,0eh;写入光标位置高八位
out dx,al
inc dx
mov al,bh
out dx,al
 
dec dx
mov al,0fh    ;写入光标位置低八位
out dx,al
inc dx
mov al,bl
out dx,al
ret

这名字我取的有点草率 大家可以自己取

大家可以看到 我们的这个函数只有一个参数

有人会说了

“你这不扯呢吗,X Y 怎么看也得有两个参数吧”

这怎么能难倒我们呢 我们用小学就学过的找规律找找不就行了(笑)

首先 大家都知道 我们的文本模式的分辨率是:80x25

也就是说 横向有80个字符 竖向有25个字符

我们发现 使用这个函数 参数如果给80 就会到下一行 也就是说 如果要控制这个光标到Y行 只要将这个Y * 80 就可以了 

那么 X呢?

我们又发现:使用这个函数时 Y*80+N 光标就会移动到Y行的第N个位置

那么 转换公式如下:

位置=Y*80+X

我们将它变成代码

void Move_Cursor(int16 x, int16 y)
{
	int res = y * 80 + x;
	ASM_call(res);
}

(int16=short)

这不就有两个参数了吗 刚刚骂街的人给我出来(bushi)

问题来了 如何清屏 不清屏我们也无法实现打印 print(主要是会变得更复杂)

我们可以通过:*(char*)(b8000+y*160+x) = 一个字符 来向屏幕上输出一个字符 可这并不能用来实现print 倒是能实现我们的清屏(clear)

有人就要问了 i为啥要自增2 而不是1

因为:

在显存(文本模式)中 这80个会占160个字节 结构如下图

​
void clear()
{
	int i;
	int j;
	for (i = 0; i < 160; i += 2)
	{
		for (j = 0; j < 25; j++)
		{
			*(char *)(0xb8000 + j * 160 + i) = ' ';
		}
	}
	Move_Cursor(0, 0);
}

​

所以 要+=2 而非++

 接下来 我们定义四个全局变量

int x = 0;//显示字符的位置
int y = 0;

/*光标的位置*/
int cons_x = 0;
int cons_y = 0;

clear函数也更改为:

void clear()
{
	int i;
	int j;
	for (i = 0; i < 160; i += 2)
	{
		for (j = 0; j < 25; j++)
		{
			*(char *)(0xb8000 + j * 160 + i) = ' ';
		}
	}
	x = 0;
	y = 0;
	cons_x = 0;
	cons_y = 0;
	Move_Cursor(cons_x, cons_y);
}

接下来 我们便要来写一个重要分支-----putchar 这个函数

学会跑之前得先学会走 输出字符串也同理 输出字符串之前 得先学会输出字符(笑)

我们之前说过可以通过*(char*)(0xb8000+y*160+x)=字符来输出 那么 我们便可以把之前的那几个变量带进去 光标在字符的前面一格就好了 我这里给出putchar的实现

void putchar(char ch)
{

	if(x == 160){
		y++;
		cons_y++;
		x = 0;
		cons_x = 0;
		Move_Cursor(cons_x, cons_y);
		
	}
	
	if (ch == '\n')
	{
		if (y == 24)
		{
			/*暂时不做什么*/
			return;
		}
		y++;
		//*(char *)(0xb8000 + cons_y * 160 + cons_x) = ' ';
		cons_y++;
		x = 0;
		
		cons_x = 0;

		return;
	}
	else if (ch == '\0')
	{
		return;
	}
	else if (ch == '\b')
	{
		if (x == 0)
		{
			return;
		}
		*(char *)(0xb8000 + y * 160 + x - 2) = ' '; /*显示位置为第23行*/
		x -= 2;
		cons_x -= 2;
		//*(char *)(0xb8000 + cons_y * 160 + cons_x + 4) = ' ';
		cons_x += 1;
		Move_Cursor(cons_x, cons_y);
		return;
	}
	//*(char *)(0xb8000 + cons_y * 160 + cons_x) = ' ';
	cons_x += 1;
	Move_Cursor(cons_x, cons_y);
	*(char *)(0xb8000 + y * 160 + x) = ch; /*显示位置为第23行*/
	x += 2;
}

然后就是putstr 输出一个C风格字符串(须要长度)

有人就要问了 为啥不直接做print呢?

做啥事都得循序渐进嘛 不要心急(笑)

我这里也给出putstr的实现

void putstr(const char *str, int length)
{
	int i;
	for (i = 0; i < length; i++)
	{
		if(y == 24 && x >= 160){
			/*暂时什么也不做*/
		}
		if (str[i] == 0x0d)
		{
			continue;
		}
		putchar(str[i]);
	}
}

然后写个getlength

int getlength(const char *str)
{
	int i;
	for (i = 0;; ++i)
	{
		if (str[i] == '\0')
		{
			return i;
		}
	}
}

最后才是 print

void print(const char *str)
{
	putstr(str, getlength(str));
}

现在 来看看我们的成果!

void HariMain(void)
{
	clear();
	print("hello, world");
	for (;;)
	{
	}
}

 下一次 我们就要让屏幕滚动起来咯(笑)

操作系统30自制操作系统--(17)命令行窗口2 本章承接上一章命令行窗口,完善了命令行的一些基本功能,诸如切换窗口光标闪烁、回车换行以及一些简单的命令反馈。 一 光标闪烁 对于主任务,按下TAB之后,需要对光标处理,使其不闪烁。 那么对于命令行任务,该如何通过HariMain来告知console_task需不需要让光标闪烁呢?这边采取的法就是像按键编码一样,通过FIFO缓冲区来传递参数。 在主函数中,如果需要切换,将光标闪烁的参数(闪烁为2,不闪为3)传递给命令行任务: if (i == ... 阅读详情

相关推荐

30自制操作系统------命令行

实现一个命令行任务,首先需要一个命令行窗口,然后需要一个命令行任务,在命令行任务中实现命令行的相关功能。   一、创建一个命令行窗口 创建命令行窗口就是在屏幕上画个窗口出来,实际就是操作显存,这一部分利用前面已经实现的makewindow8函数即可实现。   二、创建一个命令行任务 有了命令行窗口,我们再来实现命令行的功能。 (1光标闪烁功能       在刚开始命令行时,

Xuan0715的博客 3035

自制操作系统(三、完善操作系统的命令)

为了节省空间,保持在512字节以内,代码逻辑稍微复杂。这次添加关机指令ls、打开文件、运行文件等伪指令。可能有些人不想用伪指令,因为它的主要作用是装b。除了清屏关机指令以外,其他都是伪指令。实际上关机就是全屏黑色并挂起(hlt)下一次,我们真正操作文件。

linhhanpy的博客 420

30自制操作系统------增加命令行窗口

一、蜂鸣器发声 我们的操作系统还没有发声的功能,蜂鸣器发声的操作控制如下:     1、音高操作  (1)AL=0xb6;OUT(0x43,AL)  (2)AL=设定值的低8位;OUT(0x42,AL)  (3)AL=设定值的高8位;OUT(0x42,AL)  (4)设定值为0时当作65536来处理  (5)发声的音高为时钟除以设定值。也就是说设定值为10

Xuan0715的博客 753

操作系统30自制操作系统--(16)命令行窗口1

本章主要介绍创建命令行窗口,并向命令行窗口中输入字符。 一 创建命令行窗口(任务) 这边的命令行不仅仅是一个单一的窗口,而是需要新建一个任务。前面有几个计数任务B正好可以拿来改造。 下面是任务的执行程序(窗口的创建在主函数中,这边不再赘述): void console_task(struct SHEET *sheet) { struct FIFO32 fifo; struct TIMER *timer; struct TASK *task ...

sinat_33408502的博客 1053

自制操作系统 | day1

C语言、汇编自制操作系统-day1

qq_44143499的博客 587

自制操作系统 1 准备工作

最终我们的文件中需要有如下文件。前两个是终端自然不必多说。;hello-os;TAB=4指明程序的装在位置;以下的计述用于标准FAT12格式的软盘JMP entryDB 0x90启动区的名称可以是任意字符串(8字节)DW 512;每个扇区的大小(必须为512字节)DB 1;簇的大小(必须为一个扇区)DW 1;FAT的起始位置(一般从第一个扇区开始)DB 2;FAT的个数(必须为2)DW 224;根目录的大小(一般设成224项)DW 2880;

农夫果园好好喝的博客 1780

不需要学编程,自制自己的操作系统一个0基础自制操作系统的软件!详细教程!

​ 不需要学编程,自制自己的操作系统一个0基础自制操作系统的软件!详细教程一、下载或python运行不会编程的可以在自制操作系统.exe免费下载,直接跳到第二点创建.py文件,内容如下

linhhanpy的博客 3103

0xb8000 显示器可以换行输出字符

#include"gdt.h" //screen only here size #define screen_width 80 #define screen_height 25 extern "C" void clear_screen(); extern "C" void print_char(u8 x,u8 y,char c){ //firstly,check pos if(x>=screen_width){ y++; x=0; } if(y>=scree.

修也 1393

自制操作系统()

自制操作系统 我想一个操作系统(为了好玩??)。当我对同学提出这一计划时,他觉得很荒唐。于是我们打赌,我要在2年内写出一个这样的操作系统

SimbaTB的博客 4805

自制一个简单的操作系统

1 前期 下载虚拟机,我用的是VMware 下载nasm或其他软件 下载软盘映像管理工具 2 中期 新建一个txt文件,输入并保存好你的引导程序代码,将文件后缀名改为.asm,并将其放在nasm同一目录下。 下载软盘映像管理工具,笔者这里有老师给的安装包,有需要的可以私我哦~我下载的是window版的,将WinFDimgeTool.exe放到nasm同一目录下 打开nasm并输入命令:nasm 文件名1.asm -o 文件名1.bin 输入 WinFDimgeTool.exe 出.

m0_57890928的博客 5156

Day1——自制操作系统

虚拟机加载helloos.img 下载30自制操作系统光盘 将"OS\projects\01_day\helloos1"文件夹复制到"OS\tolset"文件夹下 进入"OS\tolset\helloos1"文件夹,双击"!cons_nt.bat",输入"asm",回车; 然后输入"run",回车; asm.bat 文件的含义 首先需要完成helloos.nas文件(汇编文件) 点击!cons_nt.bat后输入asm,就会在文件夹中看到helloos.img文件 在helloos.nas文件

AnitaSun的博客 3114

手把手教你制作一个操作系统

目录 写在前面 笔者目前大二,学过C++,汇编,操作系统,正在学习编译原理计算机网络,打算一个小的操作系统来巩固知识,加深对计算机的理解。 参考资料 目前正在学习《自己动手写操作系统》,资源参考一下博客: 自己动手写操作系统(高清图书+源代码)分享 开始动手 写一个最小的操作系统 一开始就遇到困难了,书中说10分钟完成一个操作系统,我花了一个小时了环境都没弄好,好在学计算机的不怕折腾,先附张结果图: 下面详述步骤: 参考文档: 《自己动手写操作系统》—— 工作环境搭建 30自制操作系统第一–Vi

qq_46354688的博客 3万+

自制操作系统-最简单的系统hello World

按照自制操作系统的步骤,首先需要使用二进制编辑器编辑一个.img文件,编辑完成之后,可以有两种运行方式: 1:可以将该img文件烧进软盘文件中,重新启动计算机 2:使用qume虚拟机运行。 我们采用第二种方式,首先我们需要获取其中的.img文件,在其光盘中的”30自制操作系统光盘\OS\projects\01_day\helloos0\ helloos.img”中。我们实现的方式...

hongbochen1223的专栏 1093

30自制操作系统之第17 命令行窗口

我们把命令行窗口单独一个新的任务。 要实现字符输入,只要在键盘被按下的时候向console_task(命令行窗口任务)的FIFO发送数据即可。但要发送数据必须要知道struct FIFO的内存地址才行。 把 struct FIFO 放到 struct TASK里面。基本上没有什么任务是完全用不到FIFO的,因此我们把它们绑定起来。struct TASK { int sel, fl

3823

自制操作系统(八、实现图形界面)

IPL.asm更新了!不用org了,org在nasm总是出问题。ipl编译一下,虚拟机看到蓝屏。其实多多少少有点伪代码的意思。这里不放代码,太多代码容易晕。现在内核代码足足有4681行。算上ipl差不多5000行。作者自己加了很多命令。

linhhanpy的博客 1692

自制操作系统日志——第十七

,我们首先继续稍微完善一下多任务的部分。然后,我们开始制作每一个操作系统都必须有的命令行窗口吧!!!从今开始,我们将一步一步的完成我们的命令行窗口,并能够输入一些命令进行调用吧! 嘿嘿嘿想想就有点激动了!!让我们现在就开始撸起袖子加油干吧。

qq_43696276的博客 473

30自制操作系统》之——第03

第三操作系统的开发才慢慢步入正轨,当然这一的内容难度较前两明显增加,还有一些汇编语言中不好理解的知识点,所以第三的学习内容要详细的记录一下。 切入正题! ---------------------------------------------------------------------------------------------------------------的...

923723914 321

30自制操作系统03_day_学习笔记

harib00a:   添加的部分从P46开始,制作IPL准备开始从磁盘装载程序了   笔者讲解了软盘的驱动的构造,以及汇编语言读取软盘的方法 MOV AX,0x0820 MOV ES,AX MOV CH,0 ; 柱面0 MOV DH,...

weixin_30381317的博客 120
lv1474
博客等级 码龄7年 0粉丝 · 1原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值