从内存读取并获取 char 数组。如果其中包含 1 个字节的 char 假定为 1 字节长度并且长度是一个数字,该怎么办
所以我正在读取 C 中应该是 BIOS 信息的内存。通过通常的读取,我得到一堆字符......这个想法是这些字符正在创建诸如锚“字符串”和 1 字节校验和和 1 字节长度之类的字段。但在C中数字是int或long。 INT 为 4 个字节。但我有 char 代表校验和,长度只占用 1 个字节(1 个字符 == 0x00 1 个字节如何将其读取为 int)
我正在这样做。 unsigned char checksum=mem[0];
前1个字节字符代表校验和。但是校验和应该是一个数字,应该是unsigned int checksum = mem[0]
..打印它打印0
然后继续这就是我如何从我的char数组获取1字节长度mem
位于索引 1 处。
length = mem[1];
//int x=mem[2];
假设如果我有两个字节数(字长数据)表示最大大小,我会在字符数组的索引 4 处这样做。
char x1[3];
memcpy(x1,&mem[4],2);
x1[2]='\0';
long v=strtol(x1,'\0',16);
上面显然是打印了我的最大值的错误结果尺寸。打印 0。而且看起来也不太对劲。 long 是 8 个字节,但我有两个字节应该代表 BIOS 中的最大大小字段。
以上可能只是错误的想法,如果我相信它是正确的或错误的。事实是我真的不知道如何处理这种转换。任何人都可以告诉我上面是错误的还是正确的。或者对我想要实现的目标有意义
这是我试图从 BIOS 中提取的 2.1 表信息。我的锚字符串打印正确,但数字字段打印不正确,我得到的最大尺寸为 0。长度为 31
https://www.dmtf.org /sites/default/files/standards/documents/DSP0134_3.0.0.pdf
这是代码
void get_it(char *arr)
{
char *mem = (unsigned char *) &arr[0];
int length, i;
unsigned char checksum=mem[0];
printf("checksum %d\n",checksum);
length = mem[1];
int x=mem[2];
int y=0;
y=mem[3];
printf("\nlength = %d version = %x\n minor version = %d",length,x,mem[3]);
char x1[3];
memcpy(x1,&mem[4],2);
x1[2]='\0';
long v=strtol(x1,'\0',16);
printf("max size %lx\n",v);
printf("entry point revision = %d\n",mem[6]);
printf("~~ %c %c %c %c %c\n",mem[12],mem[13],mem[14],mem[15],mem[16]);
/*checksum = 0;
for(i = 0; i < length; i++)
{
checksum += mem[i];
}
if(checksum == 0) break;
mem += 16;
*/
mem=mem+length;
char type=*mem;
printf("first type = %d",*mem);
printf("length = %d",*(mem+1));
int j=0;
}
int main()
{
int fd=open("/dev/mychardev-0",O_RDWR);
if(fd<=0)
{
printf("fd %d\n",fd);
exit(0);
}
size_t length=1048576;
size_t x=0;
char *buffer=malloc(sizeof(char )*length);
while(x<length)
{
int valread=read(fd,buffer,length);
printf("here\n");
if(valread==0)
{
printf("zero bytes read\n");
break;
}
if(valread<0)
{
printf("read return negative %d %d\n",valread,errno);
break;
}
x=x+valread;
}
if(x>0)
{
size_t y=0;
while(y<x)
{
if(*(buffer+y)=='_' && *(buffer+y+1)=='S' && *(buffer+y+2)=='M' && *(buffer+y+3)=='_')
{
printf("%c\n",buffer[y]);
printf("%c\n",buffer[y+1]);
printf("%c\n",buffer[y+2]);
buffer=buffer+4;
get_it(buffer);
}
y++;
}
printf("%x\n",buffer);
}
else
{
printf("ops no read\n");
}
return 0;
}
So I am reading memory that suppose to be bios info in C. And with usual read I get bunch of characters that.. The idea is those characters are making fields like Anchor "String" and 1 byte checksum and 1 Byte Length. But in C number is int or long. INT is 4 bytes. But I have char representing checksum and length is just taking 1 byte (1 character == 0x00 1 byte how to read it as int)
I am doing it like this . unsigned char checksum=mem[0];
first 1 byte character represent checksum. But check sum suppose to be a number which should be unsigned int checksum = mem[0]
.. The printing it prints 0
Then moving on this is how I get 1 byte length from my char array mem
at index 1.
length = mem[1];
//int x=mem[2];
And suppose If I have two byte number (Word length data) representing max size I am doing it like this at index 4 in my character array..
char x1[3];
memcpy(x1,&mem[4],2);
x1[2]='\0';
long v=strtol(x1,'\0',16);
Above is obviously printing wrong result for my max size. printing 0. And it does not seems all right either. long is 8 bytes But I have two byte that should represent my max size field in bios.
May be above is just wrong thinking that if I believe its correct or wrong. the fact is I really dont know how to handle this sort of conversion. Can any one please let me is above is wrong or correct. Or makes sense for what I like to achieve
This is 2.1 table info from bios I am trying to extract. My anchor strings are printing correct but number fields not printing correct I am gett 0 for max size. 31 for length
https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
This is the code
void get_it(char *arr)
{
char *mem = (unsigned char *) &arr[0];
int length, i;
unsigned char checksum=mem[0];
printf("checksum %d\n",checksum);
length = mem[1];
int x=mem[2];
int y=0;
y=mem[3];
printf("\nlength = %d version = %x\n minor version = %d",length,x,mem[3]);
char x1[3];
memcpy(x1,&mem[4],2);
x1[2]='\0';
long v=strtol(x1,'\0',16);
printf("max size %lx\n",v);
printf("entry point revision = %d\n",mem[6]);
printf("~~ %c %c %c %c %c\n",mem[12],mem[13],mem[14],mem[15],mem[16]);
/*checksum = 0;
for(i = 0; i < length; i++)
{
checksum += mem[i];
}
if(checksum == 0) break;
mem += 16;
*/
mem=mem+length;
char type=*mem;
printf("first type = %d",*mem);
printf("length = %d",*(mem+1));
int j=0;
}
int main()
{
int fd=open("/dev/mychardev-0",O_RDWR);
if(fd<=0)
{
printf("fd %d\n",fd);
exit(0);
}
size_t length=1048576;
size_t x=0;
char *buffer=malloc(sizeof(char )*length);
while(x<length)
{
int valread=read(fd,buffer,length);
printf("here\n");
if(valread==0)
{
printf("zero bytes read\n");
break;
}
if(valread<0)
{
printf("read return negative %d %d\n",valread,errno);
break;
}
x=x+valread;
}
if(x>0)
{
size_t y=0;
while(y<x)
{
if(*(buffer+y)=='_' && *(buffer+y+1)=='S' && *(buffer+y+2)=='M' && *(buffer+y+3)=='_')
{
printf("%c\n",buffer[y]);
printf("%c\n",buffer[y+1]);
printf("%c\n",buffer[y+2]);
buffer=buffer+4;
get_it(buffer);
}
y++;
}
printf("%x\n",buffer);
}
else
{
printf("ops no read\n");
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
char
是整数类型,可用于表示数字,与short
、int
或长。
它的最大值为
CHAR_MAX
。一个问题是
char
的符号是实现定义的。如有疑问,请明确使用signed char
(SCHAR_MAX
) 或unsigned char
(UCHAR_MAX
)。或者,使用 固定宽度整数类型 可以更轻松地推断字节您正在使用的数据的宽度。
EPS 表中的字段的大小表示为 BYTE、WORD 和 DWORD。这些可以分别用
uint8_t
、uint16_t
和uint32_t
表示,因为您几乎肯定需要无符号整数。此代码
尝试将最大结构大小解析为由两个字符表示的数字,这是不正确的。 最大结构大小是一个 16 位整数。
mem=mem+length;
没有多大意义,因为这会将您置于表格之外的内存中。我不确定接下来的两个 printf 调用正在尝试打印什么。此外,您的示例包含一些错误代码(未使用的变量:
i
、y
、j
)。其他一切都或多或少是正确的,尽管有些混乱。
下面是一个看起来可以在我的机器上运行的简单示例,使用
smbios_entry_point
表文件。您应该能够使用它作为参考来相应地调整您的程序。stdout:
您可能还对 dmidecode 及其源代码感兴趣。
char
is an integral type which can be used to represent numbers, the same asshort
,int
orlong
.It has a maximum value of
CHAR_MAX
.One problem is that the signedness of
char
is implementation-defined. When in doubt, be explicit withsigned char
(SCHAR_MAX
) orunsigned char
(UCHAR_MAX
).Alternatively, use fixed width integer types to make it easier to reason about the byte width of the data you are working with.
The fields in the EPS table are denoted as being of size BYTE, WORD, and DWORD. These can be represented by
uint8_t
,uint16_t
, anduint32_t
respectively, as you almost certainly want unsigned integers.This code
that attempts to parse the Maximum Structure Size as if it were a number represented by two characters is incorrect. The Maximum Structure Size is a 16-bit integer.
mem=mem+length;
does not make much sense, as this would place you in memory beyond the table. I am not sure what the twoprintf
calls that follow are trying to print.Additionally, your example includes some errant code (unused variables:
i
,y
,j
).Everything else is more-or-less correct, if messy.
Below is a simple example that seemingly works on my machine, using the
smbios_entry_point
table file. You should be able to use it as reference to adjust your program accordingly.stdout:
You may also be interested in dmidecode and its source code.