Программирование на C: Использование fread в массиве char - получить значения слегка отличающиеся от массива int - PullRequest
1 голос
/ 03 июня 2011

Я начал изучать C на своем курсе, и у меня возникли проблемы с отладкой программы, которую я делаю. Программа является эмулятором для упрощенного языка MIPS, и в основном я пытаюсь прочитать в двоичном файле 32-битные инструкции и сохранить его непосредственно в массиве, чтобы моя программа могла выполнять инструкции со счетчиком программ.

Так или иначе, в моей первой попытке программы у меня была память, в которую файл был прочитан как 32-битный массив int. Эмулятор работал нормально, и результаты моего эмулятора соответствовали ожидаемым результатам.

Спецификация хотела, чтобы эмулятор был адресуем байтом, поэтому я изменил память на массив из 1-байтовых символов. Затем я изменил остальную часть программы соответствующим образом, чтобы она читала каждую инструкцию, используя 4 блока символов.

В версии 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);

}

ИЧ в версии char:

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;

приводит к РАЗЛИЧНОМУ числу от того, что я получаю в массиве int в vm.memory [4], которое должно быть точно таким же. Результаты до vm.memory [4] одинаковы в массиве char, но по какой-то причине что-то идет не так. Кто-нибудь может помочь?

Thx

1 Ответ

3 голосов
/ 03 июня 2011

Ваш массив символов должен быть выровнен по 32-битной границе, если вы собираетесь читать / записывать 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, поэтому вы можете получить странные результаты, когда целые числа отрицательны или когда есть переполнение.

...