当前位置: 首页 > wzjs >正文

万州网站推广搜索引擎优化教材答案

万州网站推广,搜索引擎优化教材答案,wordpress ecs云服务器,品牌的佛山网站建设文章目录 1. harib02b用例(使用结构体)2. harib02c用例3. harib02d用例(显示字符图案)3. harib02e用例(增加字符图案)4. harib02g用例4.1 显示字符串4.2 显示变量值 5. harib02h用例(显示鼠标&a…

文章目录

      • 1. harib02b用例(使用结构体)
      • 2. harib02c用例
      • 3. harib02d用例(显示字符图案)
      • 3. harib02e用例(增加字符图案)
      • 4. harib02g用例
        • 4.1 显示字符串
        • 4.2 显示变量值
      • 5. harib02h用例(显示鼠标)
      • 6. harib02i用例(GDT与IDT的初始化)

1. harib02b用例(使用结构体)

由于在asmhead.nas中已经定义好的:

# asmhead.nas 节选
CYLS	EQU		0x0ff0			; 设定启动区地址
LEDS	EQU		0x0ff1
VMODE	EQU		0x0ff2			; 关于颜色的信息的地址,颜色的位数
SCRNX	EQU		0x0ff4			; 分辨率X地址
SCRNY	EQU		0x0ff6			; 分辨率Y地址
VRAM	EQU		0x0ff8			; 图像缓冲区的开始地址MOV		BYTE [VMODE],8	; 记录画面模式
MOV		WORD [SCRNX],320
MOV		WORD [SCRNY],200
MOV		DWORD [VRAM],0x000a0000

可以在bootpack.c中封装一个struct BOOTINFO,并通过访问结构体成员的方法,直接访问对应地址的内容。这样就可以直接从asmhead.nas访问到已定义好的屏幕显示信息,当屏幕显示信息修改时,显示图案可以随之修改。(BOOTINFO结构体中的字段顺序不可改变,与asmhead.nas定义好的地址强关联。)

struct BOOTINFO {char cyls, leds, vmode, reserve;short scrnx, scrny;char *vram;
};void HariMain(void)
{char *vram;int xsize, ysize;struct BOOTINFO *binfo;init_palette();binfo = (struct BOOTINFO *) 0x0ff0;xsize = (*binfo).scrnx;ysize = (*binfo).scrny;vram = (*binfo).vram;init_screen(vram, xsize, ysize);for (;;) {io_hlt();}
}

2. harib02c用例

除了使用*解引用结构体指针外,还可以使用->直接访问结构体指针的成员。因此,修改bootpack.c:

	struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;;init_palette();init_screen(binfo->vram, binfo->scrnx, binfo->scrny);

3. harib02d用例(显示字符图案)

可以通过8*16的长方形像素点阵表示字符图案,8bits是一个字节,显示一个字符图案需要使用16个字节。例如:
在这里插入图片描述
类似这种描绘文字图案的数据称为字体(font)数据。暂时使用这样一个数组表示上图中的字符“A”:

static char font_A[16] = {0x00, 0x18, 0x18, 0x18, 0x18, 0x240x24, 0x24,0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00
};

将显示字符的功能封装为一个函数,并在HariMain中调用它:

void putfont8(char *vram, int xsize, int x, int y, char c, char *font)
{int i;char *p, d /* data */;for (i = 0; i < 16; i++) {p = vram + (y + i) * xsize + x;d = font[i];// 按像素逐个将font表示出来if ((d & 0x80) != 0) { p[0] = c; }if ((d & 0x40) != 0) { p[1] = c; }if ((d & 0x20) != 0) { p[2] = c; }if ((d & 0x10) != 0) { p[3] = c; }if ((d & 0x08) != 0) { p[4] = c; }if ((d & 0x04) != 0) { p[5] = c; }if ((d & 0x02) != 0) { p[6] = c; }if ((d & 0x01) != 0) { p[7] = c; }}return;
}void HariMain(void)
{struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;static char font_A[16] = {0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24,0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00};init_palette();init_screen(binfo->vram, binfo->scrnx, binfo->scrny);				// 界面设计putfont8(binfo->vram, binfo->scrnx, 10, 10, COL8_FFFFFF, font_A);	// 白色线条显示文字for (;;) {io_hlt();}
}

显示结果为:
在这里插入图片描述

3. harib02e用例(增加字符图案)

使用OSASK字体数据(记录在hankaku.txt文件中),并使用专用工具makefont.exe将hankaku.txt文件制作成一个bin文件,接着使用bin2obj.exe工具使其生成目标文件,就可以连接到可执行文件中。最终仅需要在bootpack.c文件中extern char hankaku[4096];即可。
A的字符编码是0x41,因此A的字体图案数据的地址为hankaku+0x41*16也可以写成hankaku+'A'*16,在源文件bootpack.c添加显示字符的语句:

	putfont8(binfo->vram, binfo->scrnx,  8, 8, COL8_FFFFFF, hankaku + 'A' * 16);putfont8(binfo->vram, binfo->scrnx, 16, 8, COL8_FFFFFF, hankaku + 'B' * 16);putfont8(binfo->vram, binfo->scrnx, 24, 8, COL8_FFFFFF, hankaku + 'C' * 16);putfont8(binfo->vram, binfo->scrnx, 40, 8, COL8_FFFFFF, hankaku + '1' * 16);putfont8(binfo->vram, binfo->scrnx, 48, 8, COL8_FFFFFF, hankaku + '2' * 16);putfont8(binfo->vram, binfo->scrnx, 56, 8, COL8_FFFFFF, hankaku + '3' * 16);

显示效果为:
在这里插入图片描述

4. harib02g用例

4.1 显示字符串

由于字符串的结尾会存在一个\0,因此可以封装一个函数,传入字符串的首地址,循环字符读取,当读到0时返回:

void putfonts8_asc(char *vram, int xsize, int x, int y, char c, unsigned char *s)
{extern char hankaku[4096];for (; *s != 0x00; s++) {putfont8(vram, xsize, x, y, c, hankaku + *s * 16);x += 8;}return;
}// 调用
void HariMain(void)
{struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;init_palette();init_screen(binfo->vram, binfo->scrnx, binfo->scrny);putfonts8_asc(binfo->vram, binfo->scrnx,  8,  8, COL8_FFFFFF, "ABC 123");putfonts8_asc(binfo->vram, binfo->scrnx, 31, 31, COL8_000000, "Haribote OS.");putfonts8_asc(binfo->vram, binfo->scrnx, 30, 30, COL8_FFFFFF, "Haribote OS.");for (;;) {io_hlt();}
}

显示效果为如下图,在"Haribote OS."字符串中显示出了阴影的立体效果。
在这里插入图片描述

4.2 显示变量值

期望显示变量值,可以使用C库函数sprintf,作用就是将格式化字符串写到一个内存地址中,

void HariMain(void)
{struct BOOTINFO *binfo = (struct BOOTINFO *) 0x0ff0;char s[40];init_palette();init_screen(binfo->vram, binfo->scrnx, binfo->scrny);putfonts8_asc(binfo->vram, binfo->scrnx,  8, 8, COL8_FFFFFF, "ABC 123");putfonts8_asc(binfo->vram, binfo->scrnx, 31, 31, COL8_000000, "Haribote OS.");putfonts8_asc(binfo->vram, binfo->scrnx, 30, 30, COL8_FFFFFF, "Haribote OS.");sprintf(s, "scrnx = %d", binfo->scrnx);		// 格式化字符串写到s中putfonts8_asc(binfo->vram, binfo->scrnx, 16, 64, COL8_FFFFFF, s);for (;;) {io_hlt();}
}

显示效果为:
在这里插入图片描述

5. harib02h用例(显示鼠标)

定义鼠标的图案为16*16:

// 初始化一个鼠标图案
void init_mouse_cursor8(char *mouse, char bc)
{static char cursor[16][16] = {"**************..","*OOOOOOOOOOO*...","*OOOOOOOOOO*....","*OOOOOOOOO*.....","*OOOOOOOO*......","*OOOOOOO*.......","*OOOOOOO*.......","*OOOOOOOO*......","*OOOO**OOO*.....","*OOO*..*OOO*....","*OO*....*OOO*...","*O*......*OOO*..","**........*OOO*.","*..........*OOO*","............*OO*",".............***"};int x, y;for (y = 0; y < 16; y++) {for (x = 0; x < 16; x++) {if (cursor[y][x] == '*') {mouse[y * 16 + x] = COL8_000000;}if (cursor[y][x] == 'O') {mouse[y * 16 + x] = COL8_FFFFFF;}if (cursor[y][x] == '.') {mouse[y * 16 + x] = bc;		// bc: back-color 背景色}}}return;
}// 将鼠标图案显示在屏幕上
// vram: VRAM address
// vxsize: screen display size
// pxsize: pattern(mouse) x size
// pysize: pattern(mouse) y size
// px0: mouse location x of screen display
// py0: mouse location y of screen display
// buf: pattern address
// bxsize: roughly equal to pxsize
void putblock8_8(char *vram, int vxsize, int pxsize,int pysize, int px0, int py0, char *buf, int bxsize)
{int x, y;for (y = 0; y < pysize; y++) {for (x = 0; x < pxsize; x++) {vram[(py0 + y) * vxsize + (px0 + x)] = buf[y * bxsize + x];}}return;
}

对函数的调用:

	mx = (binfo->scrnx - 16) / 2; /* 夋柺拞墰偵側傞傛偆偵嵗昗寁嶼 */my = (binfo->scrny - 28 - 16) / 2;init_mouse_cursor8(mcursor, COL8_008484);putblock8_8(binfo->vram, binfo->scrnx, 16, 16, mx, my, mcursor, 16);

显示效果如图所示,可以显示鼠标为白色黑框,并且在左上角显示了鼠标的坐标:
在这里插入图片描述

6. harib02i用例(GDT与IDT的初始化)

GDT与IDT都是与CPU有关的设定。
为了解决多个进程访问的内存发生重叠,就需要对内存分段。将4GB的内存分成很多块(block),每一段的起始地址看起来都是0,此时任何程序都可以先写上一句ORG 0,像这样分割出来的块就称作段(segment)。也可以用分页(paging)解决问题,但是当前过多讨论。Day3中引入的段寄存器,目的就是用于分段。
为了表示一个段,需要明确一下信息:

  • 段的大小。
  • 段的起始地址。
  • 段的管理属性(禁止写入,禁止执行,系统专用)

CPU用64bits的数据表示这些信息,但是用于指定段的寄存器只有16bits。模拟调色板的方法,预先设定好段号和段的对应关系,将段号存放在段寄存器中。
段寄存器的低3bits不允许使用,因此段号可以是0 ~ 8191之间的数字,因此最多可以设置8192个段,存储这么多段的信息总共需要8192*8 = 65536Byte = 64KB(每个段的信息需要8Byte存储)。由于段号与外设无关,因此不需要使用io_out这类函数接口的调用。
这64KB的数据就被称为GDT(global segment describer table),全局段描述符表。这部分内容需要顺序写入到内存中,然后将内存地址和有效的设定个数放在CPU的GDTR(global segment describer table register)的特殊寄存器中,设定就完成了。
IDT(interrupt describer table),中断记录表。当CPU遇到外部状况变化,或内部偶然发生某些错误时,就会临时切换过去处理这种情况,被称为中断功能。
各个设备有变化时就会产生中断,中断发生后,CPU暂时停止正在处理的任务,并做好接下来能够继续处理的准备,转而执行中断程序。中断程序执行完之后,再调用事先设定好的函数,返回处理中的任务。
正式得益于中断机制,CPU可以不用一直查询键盘,鼠标,网卡等设备状态,从而专注于处理任务。
IDT记录了0 ~ 255的中断号码与调用函数的对应关系。设定GDT之前需要设定好IDT。

// GDT结构体,全局段号记录表,占8个字节
struct SEGMENT_DESCRIPTOR {short limit_low, base_low;char base_mid, access_right;char limit_high, base_high;
};// IDT结构体,中断记录表,占8个字节
struct GATE_DESCRIPTOR {short offset_low, selector;char dw_count, access_right;short offset_high;
};void init_gdtidt(void)
{// 0x27 0000 ~ 0x27ffff 共8192*8 = 65536个Byte// 由于段寄存器只有2^11 = 8192个状态struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) 0x00270000;// 0x26 f800 ~ 0x26 ffff 共256*8 = 2048个Byte// 由于中断号码共256个struct GATE_DESCRIPTOR    *idt = (struct GATE_DESCRIPTOR    *) 0x0026f800;int i;/* GDT中所有段初始化为0 */for (i = 0; i < 8192; i++) {set_segmdesc(gdt + i, 0, 0, 0);}// 分别对段号为1和2的两个段单独设置属性// 1、地址为0,上限为4G,表示全部的内存本身set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092);// 2、地址为0x280000,大小为512K,主要用作bootpack.hrb启动程序set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a);load_gdtr(0xffff, 0x00270000);		// 汇编实现定义,赋值GDTR/* IDT的初始化 */for (i = 0; i < 256; i++) {set_gatedesc(idt + i, 0, 0, 0);}load_idtr(0x7ff, 0x0026f800);		// 汇编实现定义,赋值IDTRreturn;
}void set_segmdesc(struct SEGMENT_DESCRIPTOR *sd, unsigned int limit, int base, int ar)
{if (limit > 0xfffff) {ar |= 0x8000; /* G_bit = 1 */limit /= 0x1000;}sd->limit_low    = limit & 0xffff;sd->base_low     = base & 0xffff;sd->base_mid     = (base >> 16) & 0xff;sd->access_right = ar & 0xff;sd->limit_high   = ((limit >> 16) & 0x0f) | ((ar >> 8) & 0xf0);sd->base_high    = (base >> 24) & 0xff;return;
}void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, int ar)
{gd->offset_low   = offset & 0xffff;gd->selector     = selector;gd->dw_count     = (ar >> 8) & 0xff;gd->access_right = ar & 0xff;gd->offset_high  = (offset >> 16) & 0xffff;return;
}

SEGMENT_DESCRIPTORGATE_DESCRIPTOR都是以CPU资料为基础定义的结构体,结构体size为8字节。
SEGMENT_DESCRIPTOR的指针变量初始化为0x00270000,本意是将0x00270000 ~ 0x0027ffff共64KB空间作为GDT,同样只是因为这一块区域在内存分布图中显示没有被使用,所以就直接用作GDT。同理,IDT的起始地址空间为0x0026f800 ~ 0x0026ffff

http://www.dtcms.com/wzjs/506772.html

相关文章:

  • 自己做网站教程石家庄网络推广
  • 网站开发合同 doc如何推广产品
  • 南宁网站建设网站建设搜狗网页搜索
  • wordpress首页分页代码津seo快速排名
  • 网站备案地址江门关键词排名优化
  • 网站上的链接怎么做的临沂seo公司稳健火星
  • 新乡做网站推广的营销培训方案
  • 帮你做决定的网站黑龙seo网站优化
  • 记事本做网站改变图片大小上海专业seo服务公司
  • 深圳开发的相亲网站长尾关键词挖掘精灵
  • 长春网站建设价格中国百强县市榜单
  • 阿里妈妈 wordpressseo网站推广技术
  • 电商运营方案计划书百度站长工具seo
  • 河北衡水建设网站公司电话张雪峰谈广告学专业
  • 一个手机网站网络推广渠道分类
  • 网站代理浏览器7比较经典的营销案例
  • 电商网站的二级菜单怎么做网上学电脑培训中心
  • 如何做网站授权秦洁婷seo博客
  • 网站页面的滑动怎么做优化品牌seo关键词
  • 公司网站建设选什么服务器建筑设计网站
  • 广告制作公司简介怎么写手机优化大师下载
  • 云浮新兴疫情实时动态北京百度推广优化排名
  • 做热区的网站seo的定义是什么
  • 海安做网站一份完整的营销策划书
  • 国外网站建设湖南seo推广多少钱
  • 山西网站建设免费网络营销活动策划
  • django 做网站的代码小蝌蚪幸福宝入口导航
  • 网站建设修改建议书新闻稿发布平台
  • 服务器和网站的关系跨境电商平台
  • 昆明著名网站建设软件开发定制