数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11
这篇博文,我们编写一个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的更多相关文章
- 数据段描述符和代码段描述符(一)——《x86汇编语言:从实模式到保护模式》读书笔记10
一.段描述符的分类 在上一篇博文中已经说过,为了使用段,我们必须要创建段描述符.80X86中有各种各样的段描述符,下图展示了它们的分类. 看了上图,你也许会说:天啊,怎么这么多段描述符啊!我可怎么记住 ...
- 堆、栈、数据区、bss、代码段
一个程序的运行是需要内存的,那么我们平常写的程序的内存都是怎么分配的呢 (1)首先我们要知道,内存是真实存在的,内存是一个物理器件.它时由操作系统管理的,我们平常只要使用它就行了,为了方便管理.操作系 ...
- Linux从头学08:Linux 是如何保护内核代码的?【从实模式到保护模式】
作 者:道哥,10+年的嵌入式开发老兵. 公众号:[IOT物联网小镇],专注于:C/C++.Linux操作系统.应用程序设计.物联网.单片机和嵌入式开发等领域. 公众号回复[书籍],获取 Linux. ...
- 内存布局:栈,堆,BSS段(静态区),代码段,数据段
简介 我们程序运行的时候都是放在内存里的.根据静态.成员函数.代码段.对象.等等.放在不同的内存分块里.大概分为5块 1 栈 2 堆 3 BSS段-全局区-(静态区) 4 代码段 5 数据段 栈 ...
- 静态库动态库的编译、链接, binutils工具集, 代码段\数据段\bss段解释
#1. 如何使用静态库 制作静态库 (1)gcc *.c -c -I../include得到o文件 (2) ar rcs libMyTest.a *.o 将所有.o文件打包为静态库,r将文件插入静态库 ...
- linux进程的堆栈空间_代码段(指令,只读)、数据段(静态变量,全局变量)、堆栈段(局部变量)、栈【转】
转自:http://blog.csdn.net/gongweijiao/article/details/8207333 原文参见:http://blog.163.com/xychenbaihu@yea ...
- 数据段、代码段、堆栈段、BSS段
在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...
- 不同特权级间代码段的跳转{ 门 + 跳转(jmp + call) + 返回(ret) }
[0]写在前面 0.1)我们讲 CPU的保护机制,它是可靠的多任务运行环境所必须的: 0.2) CPU保护机制:分为段级保护 + 页级保护: 0.2.1)段级保护分为:段限长 limit 检查.段类型 ...
- 高特权级代码段转向低特权级代码段(利用 ret(retf) 指令实现 jmp from ring0 to ring3)
[0]写在前面 0.1)本代码旨在演示 从 ring0 转移到 ring3(即,从高特权级 转移到 低特权级) 0.2)本文 只对 与 门相关的 代码进行简要注释,言简意赅: 0.3)文末的个人总结是 ...
随机推荐
- Mongo Windows 基本使用入门
1.安装https://www.mongodb.com/download-center#community注意:安装 "install mongoDB compass" 不勾选下载 ...
- System.Net.Http
System.Net.Http DotNet菜园 占个位置^-^ 2018-11-10 09:55:00修改 这个HttpClient的学习笔记一直迟迟未记录,只引用了其他博主的博客链接占个位置,但被 ...
- DFT到FFT的理解
DFT简化计算理解(FFT) DFT: WN=e^(-j*2*pi/N) DFT复杂度o(N^2) 降低与N^2的依赖 使N = LM (L^2+m^2 <= N^2) N点DFT分解为M ...
- 严选 Android 路由框架优化(上篇)
0 背景 早前严选 Android 工程,使用原生 Intent 方式做页面跳转,为规范参数传递,做了编码规范,使用静态方法的方式唤起 Activity public static void star ...
- nova挂载volume源码分析
当nova volume-attach instance_uuid volume_uuid 执行后,主要流程如下: 使用的存储类型是lvm+iscis 1.nova client解析该命令行,通过re ...
- 数据结构之BF算法,kmp算法,三元组,十字链表总结
在这一章中,老师教了我们四种数据结构:BF算法,kmp算法,三元组和十字链表:还给我们讲了2019年团体天体赛中T1-8的AI题 1.对于BF和kmp算法,老师除了在课堂上讲解算法的主要核心思想外,还 ...
- Kubernetes 集群部署(3) -- Flannel 集群
1. 下载包 wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64. ...
- 下载azure website的code
1.登陆kudu直接下载. http://www.concurrency.com/blog/use-azure-kudu-debug-azure-websites/ 2.FTP链接拷贝(可以忽略) 3 ...
- 华为敏捷DevOps实践:产品经理如何开好敏捷回顾会议
大家好,我是华为云DevCloud项目管理服务的产品经理 恒少:) 作为布道师和产品经理,出差各地接触客户是常态,经常和华为云的客户交流.布道.技术沙龙,但是线下交流,覆盖的用户总还是少数.我希望借助 ...
- WCF 客户端连接慢
WCF客户端第一次连接超过1分钟,以后再连接就快了. 在 Config中加入 <basicHttpBinding> <binding name="BasicHttpBind ...