x86汇编段描述符解析器

此程序可以输入描述符的低位部分和高位部分,输出段描述符的相关属性。

在windows平台上运行,原因是用到了window库函数中的INT32类型,如果需要在其他平台上运行重新定义一下INT32类型就行了

直接调用函数GetSecSignData,将参数填好就行了,执行完就会将结果段描述符的相关信息存入结构体,输出可以参考我的输出函数,我的TYPE下的a是直接存储在TYPEData中的。

代码:

​
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <iostream>
#include <string>
using namespace std;

typedef struct
{
	bool e;
	bool w;
}DataSegInfo;

typedef struct
{
	bool c, r;
}CodeSegInfo;

typedef struct
{
	bool is;
	bool a;
	DataSegInfo di;
	CodeSegInfo ci;
}TYPEData;

typedef struct
{
	UINT32 limit;
	UINT32 base;
	UINT32 TYPE;
	TYPEData typedata;
	UINT32 S;
	UINT32 DPL;
	UINT32 P;
	UINT32 AVL;
	UINT32 L;			//保留位
	UINT32 B_D;
	UINT32 G;

}SecDSignData;

INT32 TranslateHexStrToNum(char* Hex)
{
	char* hexString = Hex; // 要转换的十六进制字符串

	INT32 result;
	char* endptr;

	result = strtol(hexString, &endptr, 16); // 调用strtol函数进行转换

	return result;
}

string TranslateNumToHexStr(INT32 number)
{
	INT32 num = number; // 要转换的整型变量

	char hexString[100] = { 0 }; // 存放结果的字符串数组

	sprintf(hexString, "%X", num); // 使用%X格式化输入到字符串数组中

	return hexString;
}

int GetSecSignData(SecDSignData& out_res,
	char* in_SignLow, 
	char* in_SignHigh
)
{
	const INT32 signLow = TranslateHexStrToNum(in_SignLow);
	const INT32 signHigh = TranslateHexStrToNum(in_SignHigh);

	//得到端限长0-15位
	out_res.limit = signLow & 0xFFFF;
	//得到端限长16-19位
	out_res.limit |= (signHigh & 0xF0000);

	//得到基地址0-15位
	out_res.base = (signLow & 0xFFFF0000) >> 16;
	//得到基地址16-23位
	out_res.base |= (signHigh & 0xFF) << 16;
	//得到基地址24-31位
	out_res.base |= (signHigh & 0xFF000000);

	out_res.TYPE = (signHigh & 0xF00) >> 8;
	//计算TYPE下的子属性
	{
		out_res.typedata.is = (signHigh & 0x800) >> 11;
		if (out_res.typedata.is)	//是 1,代码段
		{
			out_res.typedata.ci.c = (signHigh & 0x400) >> 10;
			out_res.typedata.ci.r = (signHigh & 0x200) >> 9;
		}
		else						//是0,数据段
		{
			//E
			out_res.typedata.di.e = (signHigh & 0x400) >> 10;
			//W
			out_res.typedata.di.w = (signHigh & 0x200) >> 9;
		}		
		out_res.typedata.a = (signHigh & 0x100) >> 8;
	}

	out_res.S = (signHigh & 0x1000) >> 12;

	out_res.DPL = (signHigh & 0x6000) >> 13;

	out_res.P = (signHigh & 8000) >> 15;

	out_res.AVL = (signHigh & 100000) >> 20;

	out_res.L = 0;

	out_res.B_D = (signHigh & 0x400000) >> 22;

	out_res.G = (signHigh & 0x800000) >> 23;

	return 0;
}

int print_result(SecDSignData in_print)
{
	cout << "limit(段限长/段界限): " 
		<< TranslateNumToHexStr(in_print.limit)	//十六进制
		<< endl;

	cout << "base(段基地址): "
		<< TranslateNumToHexStr(in_print.base)	//十六进制
		<< endl;

	cout << "TYPE(段类型): ";

	//开始输出TYPE的子属性
	if (in_print.typedata.is == 0)	//数据段
	{
		cout << "数据段" << endl;
		cout << '\t' << "TYPE:E: " << in_print.typedata.di.e << "    " << (in_print.typedata.di.e == 0 ? "向上扩展" : "向下扩展") << endl;
		cout << '\t' << "TYPE:W: " << in_print.typedata.di.w << "    " << (in_print.typedata.di.w == 0 ? "不可写" : "可写") << endl;		
	}
	else							//代码段
	{
		cout << "代码段" << endl;
		cout << '\t' << "TYPE:C: " << in_print.typedata.ci.c << "    " << (in_print.typedata.ci.c == 0 ? "非一致代码段" : "一致代码段") << endl;
		cout << '\t' << "TYPE:R: " << in_print.typedata.ci.r << "    " << (in_print.typedata.ci.r == 0 ? "不可读" : "可读") << endl;
	}
	//输出TYPE中的a位,看是否被访问过
	cout << '\t' << "TYPE:A: " << in_print.typedata.a << "    " << (in_print.typedata.a == 1 ? "被访问过" : "未被访问过") << endl;

	cout << "S(类型标志): "
		<< in_print.S
		<< '\t' << (in_print.S == 1 ? "存储段描述符(代码段或数据段)" : "系统描述符")
		<< endl;

	cout << "DPL(描述符特权级): "
		<< in_print.DPL
		<< endl;

	cout << "P(段存在标志): "
		<< in_print.P
		<< '\t' << (in_print.P == 1 ? "存在" : "不存在")
		<< endl;

	cout << "AVL(系统软件可用位,由操作系统来用): "
		<< in_print.AVL
		<< endl;

	cout << "L(保留位): "
		<< in_print.L
		<< endl;

	cout << "B/D(默认操作数大小): "
		<< in_print.B_D
		<< '\t' << (in_print.B_D == 0 ? "16位" : "32位")
		<< endl;

	cout << "G(颗粒度标志): "
		<< in_print.G
		<< '\t' << (in_print.G == 0 ? "单位:B" : "单位:4KB")
		<< endl;

	return 0;
}

int main()
{
	while (1)
	{
		char SecDescribeLow[100] = { 0 };
		char SecDescribeHigh[100] = { 0 };

		printf("输入段描述符的低32位:");
		scanf("%s", SecDescribeLow);
		printf("输入段描述符的高32位:");
		scanf("%s", SecDescribeHigh);

		SecDSignData info;

		GetSecSignData(info, SecDescribeLow, SecDescribeHigh);

		print_result(info);

		printf("\n");
	}

	return 0;
}

​

写这个程序的原因是在学习x86汇编:从实模式到保护模式中发现阅读段描述符十分不方便,所以制作了这个程序帮助查阅段描述符的相关属性,希望可以帮助其他正在学习汇编的人

相关推荐

  1. x86汇编描述符解析

    2024-02-19 10:50:03       49 阅读
  2. x86汇编伪指令align和p2align

    2024-02-19 10:50:03       22 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-02-19 10:50:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-02-19 10:50:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-02-19 10:50:03       82 阅读
  4. Python语言-面向对象

    2024-02-19 10:50:03       91 阅读

热门阅读

  1. 如何系统地自学Python:一个全面指南

    2024-02-19 10:50:03       57 阅读
  2. CSS杂记

    CSS杂记

    2024-02-19 10:50:03      38 阅读
  3. 3.1.爬虫

    2024-02-19 10:50:03       37 阅读
  4. go依赖注入库samber/do使用

    2024-02-19 10:50:03       59 阅读
  5. c++指针和引用的区别

    2024-02-19 10:50:03       51 阅读
  6. synchronized使用

    2024-02-19 10:50:03       51 阅读
  7. TOP100 图论

    2024-02-19 10:50:03       50 阅读
  8. 2024/2/18 图论 最短路入门 floyd 1

    2024-02-19 10:50:03       55 阅读
  9. 2024/2/18 图论 最短路入门 dijkstra 2

    2024-02-19 10:50:03       66 阅读
  10. 【图论经典题目讲解】洛谷 P5304 旅行者

    2024-02-19 10:50:03       53 阅读
  11. fabric-contract-api-go快速上手

    2024-02-19 10:50:03       54 阅读
  12. k8s的一些关键信息(归类摘抄,非提炼)

    2024-02-19 10:50:03       39 阅读