Имитация базового машинного языка на C. - PullRequest
1 голос
/ 16 сентября 2011

Так что для моего задания мне нужно смоделировать базовый машинный язык с C. Машина имеет 16 регистров (reg []), счетчик программ (pc) и память (mem []), которые все являются беззнаковыми символами. Инструкции считываются из файла и имеют формат:

B404 (1RXY = Загрузить регистр R со значением по адресу памяти XY). Все числа в шестнадцатеричном виде. C000 - команда остановки.

Теперь моя проблема в том, что когда я распечатываю инструкции (при сохранении в a, b, c, d и cd), b и d имеют начальные нули. Как мне от них избавиться, чтобы инструкция печаталась как выше? (Строка 48).

Кроме того, некоторые из моих операторов if выглядят не так, как будто я помещаю в них printf (), а они находятся в файле, который никогда не печатается. (Строки от 48 до 78).

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main () {
FILE *file;
file = fopen("a3.txt","r");
unsigned int temp = 0;
unsigned char pc, mem[256], reg[16],a,b,c,d,cd;
unsigned int count;
count = 0;
pc = 0;
for (int i=0; i < 16;++i) {
    reg[i] = 0;
}

if (file == NULL) {
    printf("\n Error opening the file");
    exit(0);
}
for (int i=0; !feof(file); i += 2) {
    fscanf(file, "%X", &temp);
    mem[i] = ((temp & 0xFF00) >> 8);
    mem[i + 1] = (temp & 0xFF);
    if (feof(file)) {
        break; // exit from while
    }
    ++count;
}
int fclose(FILE *file);
/*while (mem[pc] != 0xC0) {*/
for (unsigned int i=0; i < count-1;++i) {
    if (mem[i] == 0xC0) {
        break; // exit from for
        exit(1);
    }
    cd = mem[pc + 1];
    a = (mem[pc] & 0xF0);
    b = (mem[pc] & 0xF);
    c = (mem[pc + 1] & 0xF0);
    d = (mem[pc + 1] & 0xF);
    printf("%02X ",pc);
    printf("%X%X%X%X - [",a,b,c,d);
    printf("%02X %02X %02X %02X ",reg[0],reg[1],reg[2],reg[3]);
    printf("%02X %02X %02X %02X ",reg[4],reg[5],reg[6],reg[7]);
    printf("%02X %02X %02X %02X ",reg[8],reg[9],reg[10],reg[11]);
    printf("%02X %02X %02X %02X]\n",reg[12],reg[13],reg[14],reg[15]);
    if (a == 0x1) {
        reg[b] = reg[cd];
    }
    if (a == 0x2) {
        reg[b] = cd;
        //printf("2 reporting in");
    }
    if (a == 0x3) {
        reg[cd] = reg[b];
    }
    if (a == 0x4) {
        reg[d] = reg[c];
    }
    if (a == 0x05) {
        reg[d] = (reg[b] + reg[c]);
        //printf("5 reporting in");
    }
    if (a == 0x7) {
        reg[d] = (reg[b] | reg[c]);
    }
    if (a == 0x8) {
        reg[d] = (reg[b] & reg[c]);
    }
    if (a == 0x9) {
        reg[d] = (reg[b] ^ reg[c]);
    }
    if (a == 0xA0) {
        reg[b] = (reg[b] >> reg[d]) | (reg[b] << (32 - reg[d]));
    }
    pc += 2;
    if (a == 0xB0) {
        //printf("B reporting in");
        if (reg[b] == reg[0]) {
            pc = cd;
        }
    }
}
return 0;
}

Спасибо!

1 Ответ

1 голос
/ 16 сентября 2011

Чтобы получить старшие биты беззнакового символа, используйте следующую функцию:

unsigned char hi(unsigned char bits) {
  return (bits >> 4) & 0x0F;
}

И когда вы выполняете диспетчеризацию инструкций, лучше использовать оператор switch вместо if ... else if ... else каскад.Тогда вы можете иметь простой default: fprintf(stderr, "unknown instruction: %u\n", a); exit(1); для обнаружения ошибок.

Кроме того, 0xA0 - это не значение 10, а 160, поэтому вы должны либо написать 10, либо 0x0A.

Обновление:

Код для извлечения a, b, c и d должен выглядеть следующим образом:

a = (mem[pc + 0] >> 4) & 0x0F;
b = (mem[pc + 0] >> 0) & 0x0F;
c = (mem[pc + 1] >> 4) & 0x0F;
d = (mem[pc + 1] >> 0) & 0x0F;

Это легко прочитать и легко проверить на правильность.Хорошо видно равномерное обращение, и что каждое значение ограничено диапазоном [0x00;0x0F].

...