Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C FAT-BPB与小端反转_C_Disk_Endianness_Fat - Fatal编程技术网

C FAT-BPB与小端反转

C FAT-BPB与小端反转,c,disk,endianness,fat,C,Disk,Endianness,Fat,我的CPU是little endian,文档告诉我它符合FAT规范的字节顺序。那么,为什么我得到的是第一个扇区的字节0-3的有效地址,而不是第一个扇区的字节11-12的有效地址 116 int fd = open (diskpath, O_RDONLY, S_IROTH); 117 118 read (fd, BS_jmpBoot, 3); 119 printf("BS_jmpBoot = 0x%02x%02x%02x\n", BS_jmpBoo

我的CPU是little endian,文档告诉我它符合FAT规范的字节顺序。那么,为什么我得到的是第一个扇区的字节0-3的有效地址,而不是第一个扇区的字节11-12的有效地址

116         int fd = open (diskpath, O_RDONLY, S_IROTH);
117 
118         read (fd, BS_jmpBoot, 3);
119         printf("BS_jmpBoot = 0x%02x%02x%02x\n", BS_jmpBoot[0], S_jmpBoot[1], S_jmpBoot[2]);
120 
121         read (fd, OEMName, 8);
122         OEMName[8] = '\0';
123         printf("OEMName = %s\n", OEMName);
124 
125         read (fd, BPB_BytesPerSec, 2);
126         printf("BPB_BytesPerSec = 0x%02x%02x\n",BPB_BytesPerSec[0], BPB_BytesPerSec[1]);
屈服

BS_jmpBoot = 0xeb5890                  //valid address, while 0x9058eb would not be
OEMName = MSDOS5.0
BPB_BytesPerSec = 0x0002               //Should be 0x0200
我想弄清楚为什么Bp_jmpBoot和OEMName打印有效,而Bp_BytesPerSec不有效。如果有人能启发我,我将不胜感激

谢谢

编辑:谢谢大家的帮助,是我的类型让一切都出了差错。正如uesp所建议的(有点),我通过将字节写入一个无符号的短字符来实现它,但我仍然想知道为什么这不起作用:

            unsigned char BPB_BytesPerSec[2];
...
125         read (fd, BPB_BytesPerSec, 2);
126         printf("BPB_BytesPerSec = 0x%04x\n", *BPB_BytesPerSec);
屈服 BPB_BytesPerSec=0x0000

我想使用字符数组来分配空间,因为我想确定我在任何机器上写入的空间;还是我不应该


再次感谢

首先,这一行:

printf("BPB_BytesPerSec = 0x%02x%02x\n",BPB_BytesPerSec[0], BPB_BytesPerSec[1]);
正在以big-endian格式打印值。如果它在这里打印
0x0002
,实际值将是
0x0200
,以小尾端为单位

至于
BS_jmpBoot
值,根据:

前三个字节eb3c和90反汇编为JMP SHORT 3C NOP。(3C值可能不同。)其原因是跳过磁盘格式信息(BPB和EBPB)。由于磁盘的第一个扇区加载到位置0x0000:0x7c00处的ram中并执行,如果没有此跳转,处理器将尝试执行非代码的数据


换句话说,前3个字节是操作码,它们是三个独立的字节,而不是一个小的endian值。

您错误地读取了
BPB_bytespercc
。Bpb的结构是(来自):

前两个字段是字节,所以它们的尾数是不相关的(我认为)
BPB_BytesPerSec
是一个单词(假设为2个字节),因此您应该像这样定义/阅读它:

WORD BPB_BytesPerSec;            //Assuming WORD is defined on your system
read (fd, &BPB_BytesPerSec, 2);
printf("BPB_BytesPerSec = 0x%04x\n", BPB_BytesPerSec); 

因为当你直接读取字节时,你会得到
0002
,在little endian中是
0x0200
,你应该像这样正确地读取
BPB_bytespercc

read(fd,BS_jmpBoot,3)-->
读取(fd,BS_jmpBoot,4)顺便说一句,什么是
BS_jmpBoot
?@wildplasser-在古老的软盘中,引导扇区可能包含可执行代码-用于DOS的代码为16位8086机器代码。一旦进入RAM,就直接跳到启动扇区的开始。然而,在引导扇区的开头有一些保留字段描述磁盘格式——根据DOS版本的不同,512个字节中最多有64个字节——因此前三个字节是为跳转指令保留的,用于真正的可执行代码我指的是没有对
BS_jmpBoot
的定义,但事实上(正确的方法是在一次扫描中读取完整的512字节扇区,然后选择正确的片段。@wildplasser-我想现在这是针对软盘映像文件的,所以如果您不介意平台特定的代码,一个选项是使用内存映射文件。就我个人而言,在读取二进制文件时,我有一个库,它在e background并提供了一系列
peek
方法-主要用于防止文件读取、endian和类似问题干扰解析。BS_jmpBoot的字节是正确的-对于DOS,“E9 XX XX XX”表示16位跳转或“EB XX 90”对于后跟NOP的短跳转,无论哪种方式跳转到启动代码。但是,正如uesp所说,该字段是一个字节序列(包含16位x86机器代码)-endianness不适用。在输出前粘贴一个
0x
,并不意味着字节序列不是字节序列。每个扇区的字节的问题是,他没有将组件字节转换回单个值-这就是你担心endianness的原因。我完全理解p问题是。我只是想用最简单的方式来解释。我可能没有很好地解释。我不是想反驳,只是建议可能的调整。
WORD BPB_BytesPerSec;            //Assuming WORD is defined on your system
read (fd, &BPB_BytesPerSec, 2);
printf("BPB_BytesPerSec = 0x%04x\n", BPB_BytesPerSec);