C编程: Using fread into char array - get very slightly different values from int array

标签 c char int emulation

我已经开始在我的类(class)中学习 C,但我在调试我正在制作的程序时遇到了一些麻烦。该程序是一个简化的 MIPS 语言的模拟器,基本上我正在尝试读取 32 位指令的二进制文件并将其直接存储到数组中,以便我的程序可以通过程序计数器执行指令。

无论如何,在我第一次尝试该程序时,我将文件作为 32 位 int 数组读入内存。模拟器运行良好,我的模拟器的结果符合预期结果。

然而,规范希望模拟器是字节可寻址的,所以我将内存更改为 1 字节字符数组。然后我适本地更改了程序的其余部分,以确保它通过获取 4 个字符 block 来读取每条指令。

在我的模拟器的 int 版本中:

int loadBin(char path[]) {

printf("%s\n",path);

//open file
FILE *fp;
if ((fp = fopen(path, "rb")) == NULL) {
    perror("Error opening binary file");
    return 1;
}
//read from file to memory
fread(&vm.memory, 4, 16384, fp);

}

并且在字符版本中:

int loadBin(char path[]) {
//open file
FILE *fp;
if ((fp = fopen(path, "rb")) == NULL) {
perror("Error opening binary file");
return 1;
}
//read from file to memory
fread(&vm.memory, 1, 65536, fp);
fclose(fp);

return 0;
}

但 char 内存模拟器在程序中途读取了一条错误的 32 位指令。

使用:

int test = (vm.memory[16]) + (vm.memory[17] << 8) +
(vm.memory[18] << 16) + (vm.memory[19] << 24);
printf("%d\n", test);
return 0;

结果与我在 vm.memory[4] 的 int 数组中得到的数字不同,这应该完全相同。直到 vm.memory[4] 的结果在 char 数组中是相同的,但由于某种原因出了问题。有人可以帮忙吗?

谢谢

最佳答案

如果您要从中读取/写入 32 位字,则您的 char 数组应该在 32 位边界对齐。如果您使用 malloc 分配这个数组,那么它已经对齐了。

取而代之的是:

int test = (vm.memory[16]) + (vm.memory[17] << 8) +
(vm.memory[18] << 16) + (vm.memory[19] << 24);

试试这个:

int test = (vm.memory[16]) | (vm.memory[17] << 8) |
(vm.memory[18] << 16) | (vm.memory[19] << 24);

| 是按位或运算符。 + 使用 2 的补码算法,因此当整数为负数或出现溢出时,您可能会得到奇怪的结果。

关于C编程: Using fread into char array - get very slightly different values from int array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6228945/

相关文章:

C 标准库和目标文件

c - 这个条件部分是如何工作的?

java - 定义 isJavaIdentifierStart 方法

c 字符串,字符指针 : need help printing the string and some advice

java - 为什么下面的代码不起作用,除非数组是 Integer[],而不是 int[]

c - "stderr;"作为语句不抛出警告

c - 搜索二进制数

c - 使用 getchar();定义多个变量

java - 从不同的 .txt 文件获取 INT 并将它们加在一起

scala - 为什么 chisel UInt(32.W) 不能取 bit[32] 恰好为 1 的无符号数?