这篇博文,我们编写一个C语言的小程序,来解析数据段或者代码段描述符的各个字段。这样我们阅读原书的代码就会方便一点,只要运行这个小程序,就可以明白程序中定义的数据段或者代码段的描述符了。

这段代码,我用了“位字段”的知识,这还是第一次使用C语言的这个特性呢,如果有不对的地方,欢迎博友斧正。

写代码之前,我们再复习一下数据段描述符和代码段描述符的格式。(图片选自赵炯老师的《Linux内核完全剖析》)

#include <stdio.h>

//定义描述符中的低32位
struct seg_des_low_word
{
unsigned int limit_0_15:16;
unsigned int base_0_15 :16; };
//定义描述符中的高32位
struct seg_des_high_word
{
unsigned int base_16_23 :8;
unsigned int type :4;
unsigned int s :1;
unsigned int dpl :2;
unsigned int p :1;
unsigned int limit_16_19:4;
unsigned int avl :1;
unsigned int l :1;
unsigned int d_b :1;
unsigned int g :1;
unsigned int base_24_31 :8;
};
//对TYPE字段进行解析
void parse_type(unsigned int t)
{
if(t<=7)
printf("数据段: ");
else
printf("代码段: ");
switch(t)
{
case 0:
case 1:
printf("只读\n");
break;
case 2:
case 3:
printf("可读可写\n");
break;
case 4:
case 5:
printf("向下扩展,只读\n");
break;
case 6:
case 7:
printf("向下扩展,可读可写\n");
break;
case 8:
case 9:
printf("仅执行\n");
break;
case 10:
case 11:
printf("可读,可执行\n");
break;
case 12:
case 13:
printf("一致性段,仅执行\n");
break;
case 14:
case 15:
printf("一致性段,可读,可执行\n");
break;
default:
break; } } void parse_seg_des(struct seg_des_low_word* pl, struct seg_des_high_word* ph)
{
unsigned int seg_base;
//拼接基地址字段
    seg_base = (ph->base_24_31<<24)|(ph->base_16_23<<16)|pl->base_0_15;
printf("seg_base = %#X\n",seg_base); unsigned int seg_limit;
//拼接段限长字段
    seg_limit = (ph->limit_16_19<<16)|pl->limit_0_15;
printf("seg_limit = %#X\n",seg_limit); //下面的字段输出是不是很方便?这就是位字段的好处之一
    printf("S = %d\n",ph->s);
printf("DPL = %d\n",ph->dpl);
printf("G = %d\n",ph->g);
printf("D/B = %d\n",ph->d_b);
printf("TYPE = %d\n",ph->type);
    //解析TYPE(目前只支持数据段描述符和代码段描述符,其他类型的,可以自己扩充)
parse_type(ph->type);
} int main(void)
{
printf("please input the segment descriptor, low= high=\n");
struct seg_des_high_word *high;
struct seg_des_low_word *low; unsigned int l_word = 0;
unsigned int h_word = 0; //请求用户输入描述符,先是低32位,再是高32位
    scanf("%x" "%x",&l_word,&h_word);
printf("-----------------------\n");
high =(struct seg_des_high_word*)&h_word;
low =(struct seg_des_low_word*)&l_word; parse_seg_des(low,high);
printf("------------------------\n"); return 0;
}

好了,代码就是这样。下面看看结果吧。编译后并运行。提示我们输入:

我们就输入原书的配书代码c11_mbr.asm中

  ;创建#1描述符,保护模式下的代码段描述符
mov dword [bx+0x08],0x7c0001ff
mov dword [bx+0x0c],0x00409800

注意,输入格式是16进制(不需要前导的0x),先输入低32位,也就是7c0001ff,然后空格,再输入高32位,也就是00409800,最后回车,就出结果了。

效果还不错吧。哈哈。

(完)

数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11的更多相关文章

  1. 数据段描述符和代码段描述符(一)——《x86汇编语言:从实模式到保护模式》读书笔记10

    一.段描述符的分类 在上一篇博文中已经说过,为了使用段,我们必须要创建段描述符.80X86中有各种各样的段描述符,下图展示了它们的分类. 看了上图,你也许会说:天啊,怎么这么多段描述符啊!我可怎么记住 ...

  2. 堆、栈、数据区、bss、代码段

    一个程序的运行是需要内存的,那么我们平常写的程序的内存都是怎么分配的呢 (1)首先我们要知道,内存是真实存在的,内存是一个物理器件.它时由操作系统管理的,我们平常只要使用它就行了,为了方便管理.操作系 ...

  3. Linux从头学08:Linux 是如何保护内核代码的?【从实模式到保护模式】

    作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...

  4. 内存布局:栈,堆,BSS段(静态区),代码段,数据段

    简介 我们程序运行的时候都是放在内存里的.根据静态.成员函数.代码段.对象.等等.放在不同的内存分块里.大概分为5块 1  栈 2  堆 3 BSS段-全局区-(静态区) 4 代码段 5 数据段 栈 ...

  5. 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释

    #1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...

  6. linux进程的堆栈空间_代码段(指令,只读)、数据段(静态变量,全局变量)、堆栈段(局部变量)、栈【转】

    转自:http://blog.csdn.net/gongweijiao/article/details/8207333 原文参见:http://blog.163.com/xychenbaihu@yea ...

  7. 数据段、代码段、堆栈段、BSS段

    在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...

  8. 不同特权级间代码段的跳转{ 门 + 跳转(jmp + call) + 返回(ret) }

    [0]写在前面 0.1)我们讲 CPU的保护机制,它是可靠的多任务运行环境所必须的: 0.2) CPU保护机制:分为段级保护 + 页级保护: 0.2.1)段级保护分为:段限长 limit 检查.段类型 ...

  9. 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)

    [0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...

随机推荐

  1. C# / .Net Core 访问MongoDb库

    话不多说直接上代码 连接字符串: { "AppSettings": { "mongodb": "mongodb://用户名:密码@IP地址:端口号&q ...

  2. vs2015+opencv3.3.1+ c++实现 静态背景下多运动目标提取,检测

    静止背景下运动物体的提取,跟踪出运动轨迹 下载地址 https://download.csdn.net/download/li_haoren/10761361 1.两遍扫描法得到第n帧的连通域,分离出 ...

  3. 微信H5或PC支付常见问题汇总

    1.H5端调起支付,直接提示[支付失败],打印具体的信息,“<当前URL不存在>” 原因: ①.[支付授权目录不对]---查看微信商户平台的支付授权目录的地址,如果MVC结构的,则只需填写 ...

  4. day8学python 各种简单模板

    各种简单模板 内容: 1.shelve模板 存储数据 2.shutil 模板 用作拷贝/删除/压缩文件(使用便捷) 3.hashlib 模板 加密文件 4.re模板 ================= ...

  5. Codeforces Round #551 (Div. 2)B. Serval and Toy Bricks

    B. Serval and Toy Bricks time limit per test 1 second memory limit per test 256 megabytes input stan ...

  6. c语言指针的简单实例

    c语言的指针的存在使得c语言对硬件的操控,以及灵活性得到了极大的提高. 但是指针的使用存在着很多难点问题. #include<stdlib.h> #include<stdio.h&g ...

  7. python基础之内建函数(二)

    (7)max() 函数:返回列表.元祖或字符串中最大的元素,注意:字母“大于”数字.小写字母“大于”大写字母(字母排序是根据ASCII码表排的) 例如: >>>num = list ...

  8. Python博文列表

    手把手|100行Python代码自动抢火车票!(包教包会):https://zhuanlan.zhihu.com/p/32928355 最全中华古诗词数据库, :https://github.com/ ...

  9. adminlte+layui框架搭建1

    之前写过一篇layui-master的UI搭建,但是感觉layui-master缺少一些东西(前台页面不过多研究),比如说页面的皮肤.菜单.插件,当然我也希望layui的插件可以越来越多,支持多个浏览 ...

  10. tornado 03 请求与响应

    tornado 03 请求与响应 一.请求与响应 浏览器与服务器之间沟通的到底是什么信息 #服务器在后台一直保持运行着 #浏览器通过URL(路由.地址)发送请求 #服务器接收请求了通过tornado处 ...