此程序可以输入描述符的低位部分和高位部分,输出段描述符的相关属性。
在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汇编:从实模式到保护模式中发现阅读段描述符十分不方便,所以制作了这个程序帮助查阅段描述符的相关属性,希望可以帮助其他正在学习汇编的人