2011-09-16 7 views
1

私の割り当てのために、C言語で基本的な機械語をシミュレートする必要があります。このマシンには16個のレジスタ(reg [])、プログラムカウンタ(pc)、メモリこれは符号なしの文字です。命令はファイルから読み込まれ、Cでの基本的な機械語のシミュレーション

B404(1RXY =メモリアドレスXYの値を持つレジスタRをロード)の形式です。すべての数字は16進数です。 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

以前の質問に回答した場合、さらに回答が得られるかもしれませんか? – StuartLC

+1

あなたの割り当て - それはあなたによって行われるはずです;) – c69

+0

私ができる限りそれをやったことがわかります。私はそれが私がそれを望むように働いていない理由について私が行方不明の小さな何かがあると感じるだけです。 – RedFred

答えて

1

unsigned char型の高ビットを取得するには、次の関数を使用します。

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

そして、あなたは命令ディスパッチを行っているとき、if ... else if ... elseカスケードの代わりにswitchステートメントを使用することをお勧めします。次に、エラー検出のために単純なdefault: fprintf(stderr, "unknown instruction: %u\n", a); exit(1);を使用できます。

また、0xA0は値10ではなく160ですので、10または0x0Aのいずれかを入力する必要があります。

更新:

abcdを抽出するためのコードは次のようになります。

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]に制限されています。

+0

ありがとう!今私はswitch文を実装しようとしています。 – RedFred

+0

経験豊富なプログラマーがこの割り当てをどのように実装するかを知りたければ、ここにはhttp://roland-illig.de/tmp/machine.cがあります。しかし、これを提出またはコピーすることについても考えないでください。あなたはコードを比較して、私がどのようにしたのかを知りたいかもしれません。 –