-1

これは少し大きな質問になるでしょう (少なくとも私にはそう思われます) ので、ご容赦ください。私たちは C で y86 シミュレーターを作成しており、割り当てのこの部分は、ファイルを開き、メモリにロードし、ダンプを実行して終了することになっています。main メソッドはこれらのことを行うために提供されています。実際にロードを行うために loader.c および loader.h ファイルを作成するだけです。load 関数は、ロードが成功した (入力ファイルにエラーがなかった) 場合は true(1) を返し、それ以外の場合は false(0) を返します。現在、ロード機能で行き詰まっており、問題は loader.c の 58 ~ 67 行目あたりにあると思います。メソッドを適切に呼び出していませんが、数値を適切にフォーマットする方法がわかりません。Cで作業するのはこれが初めてなので、まだかなり混乱しています。必要に応じて、さらにコードを提供できます。これまで、loader.c をインクルードしました。loader.h、memory.c、および memory.h。Bool.h が含まれていますが、これは true-false の typedef にすぎないので、省略できると考えました。これが少し多すぎる場合は申し訳ありませんが、私は完全に困惑しており、他にどこに行くべきかわかりません. 与えられた助けを前もって本当にありがとう、それは大歓迎です!

loader.c:

1   #include <stdio.h>
2   #include <string.h>
3   #include "loader.h"
4   #include "bool.h"
5   #include "memory.h"
6  
7   bool checkAddressFormat (char addressArray[]);
8   bool checkDataFormat(char dataArray[]);
9   bool isDigit(char character); 
10  bool checkLine(char inputLine[]);
11 
12  int load(int argc, char *argv[]){
13 
14      if (argc != 2){
15          printf("file opening failed \nusage: yess <filename>.yo\n");
16          return 0;
17      }
18      else{
19          //Checks that all the files exist
20          FILE* file = fopen(argv[1], "r" );
21          char* ext;
22          ext = strrchr(argv[1], '.'); //Grab extension
23          if (file == 0 || strcmp(ext,".yo") != 0) {
24              printf("file opening failed \nusage: yess <filename>.yo\n");
25              return 0;
26          }
27         else{
28             char inputLine[250]; //The current line being used
29             int intLine[250];
30             int ch;
31             int i;
32             int j;
33             int k;
34             int m;
35             bool lineCheck;
36             bool memError = FALSE;
37             int byteAddress;
38             int lineNumber = 1;
39             
40             ch = fgetc(file); //Grab first character
41             while (!feof(file)) //While file is not empty
42             {
43                 while(ch != '\n'){
44                     inputLine[i] = ch;
45                     intLine[i] = ch;
46                     ch = fgetc(file);
47                 }
48                 char addressString[4];
49                 addressString[3] = '\0';
50                 for(j = 0; j < 3; j++){ //Creates char array of address on current line.
51                      addressString[j] = inputLine[j+4];
52                 }
53                 byteAddress = atoi(addressString); //Turns the array into an int to pass to putByte
54 
55                 unsigned char dataString[12];
56                 for(k = 0; k < 12; k++) {
57                      dataString[k] = (unsigned char)intLine[k+9];
58                 }
59 
60                 if(checkLine(inputLine) == FALSE){
61                     printf("Error on line %d:\n",lineNumber);
62                     printf("%s\n",inputLine);
63                     return 0;
64                 }
65                 
66                 else{
67                     for(m = 0; m < 250; m++) {
68                         putByte(byteAddress, dataString[m], &memError);
69                     }
70                     printf("call putByte");
71                 }
72 
73                 for(i = 0; i < 250; i++){
74                     inputLine[i] = ' ';
75                     intLine[i] = ' ';
76                 }
77                 printf("clear arrays");
78                 lineNumber++;
79                 ch = fgetc(file);
80             }
81         }
82         close(file);
83      }
84      return 1;
85  }
86 
87  bool checkLine(char inputLine[]){
88      
89      if(checkDataFormat(inputLine) == FALSE || checkAddressFormat(inputLine) == FALSE){
90          return FALSE;
91      }
92      else if(inputLine[22] != '|'){
93          return FALSE;
94      }
95      else {
96          return TRUE;
97      }
98 
99  }
100 bool checkDataFormat(char dataArray[]) {
101     int i;
102     bool temp;
103     int counter = 0;
104     for(i = 9; i <= 20; i++) {
105         temp = isDigit(dataArray[i]);
106         if(temp  == TRUE){
107             counter++;
108         }
109     }
110     if(counter > 12){
111         return FALSE;
112     }
113     else{
114         return TRUE;
115     }
116 }
117
118 bool checkAddressFormat(char addressArray[]) {
119     if(isDigit(addressArray[2]) == FALSE || isDigit(addressArray[4]) == FALSE || isDigit(addressArray[5])  == FALSE || isDigit(addressArray[6]) == FALSE)
120         return FALSE;
121     if(addressArray[3] != 'x')
122         return FALSE;
123     if(addressArray[7] != ':')
124         return FALSE;
125     else
126         return TRUE;
127 }
128
129 bool isDigit(char character) {
130     if(character == '0' || character == '1' || character == '2' || character == '3' ||
131        character == '4' || character == '5' || character == '6' || character == '7' ||
132        character == '8' || character == '9' || character == 'a' || character == 'b' ||
133       character == 'c' || character == 'd' || character == 'e' || character == 'f')
134       return TRUE;
135    else
136        return FALSE;
137}
138

loader.h:

1    #ifndef LOADER_H
2    #define LOADER_H
3
4    int load(int argc, char *argv[]);
5
6    #endif

メモリ.c:

1   #define MEMSIZE 1024     //1024 words of memory
2   #ifndef MEMORY_H
3   #define MEMORY_H
4   #include "bool.h"
5 
6   static unsigned int memArray[MEMSIZE];
7 
8 
9   unsigned int fetch(int address, bool * memError){
10   
11      if(address < 0 || address > 1024)
12          (*memError) = TRUE;
13      else{
14          (*memError) = FALSE;
15          return memArray[address];
16      }
17  }
18
19  void store(int address, unsigned int value, bool * memError){
20      if(address < 0 || address > 1024)
21          (*memError) = TRUE;
22      else{
23          (*memError) = FALSE;
24          memArray[address] = value;
25      }
26  }
27
28  unsigned char getByte(int byteAddress, bool * memError){
29      if(byteAddress < 0 || byteAddress > 4095){
30          (*memError) = TRUE;
31          return 0;
32      }
33      else{
34          (*memError) = FALSE;
35          int wordAddress = fetch((byteAddress/4), memError);
36          char * x = (char*)&wordAddress;
37          char temp = x[(byteAddress%4)];
38          return temp;
39      }
40  }
41  void putByte(int byteAddress, unsigned char value, bool * memError){
42      if(byteAddress < 0 || byteAddress > 4095)
43          (*memError) = TRUE;
44      else{
45          (*memError) = FALSE;
46          int wordAddress = fetch((byteAddress/4), memError);
47          char * x = (char*)&wordAddress;
48          x[(byteAddress%4)] = value;
49          store(byteAddress/4, wordAddress, memError);
50      }
51  }
52  void clearMemory(){
53
54      int i;
55      for(i=0;i<MEMSIZE;i++){
56          memArray[i] = 0;
57      }
58
59  }
60  //Address must be multiple of 4
61  unsigned int getWord(int byteAddress, bool * memError){
62
63      if(byteAddress < 0 || byteAddress > 4095 || (byteAddress%4) != 0){
64          (*memError) = TRUE;
65          return 0;
66      }
67      else{
68          int word = fetch(byteAddress/4, memError);
69          (*memError) = FALSE;
70          return word;
71      }
72  }
73  //Address must be multiple of 4
74  void putWord(int byteAddress, unsigned int value, bool * memError){
75
76     if(byteAddress < 0 || byteAddress > 4095 || (byteAddress%4) != 0){
77          (*memError) = TRUE;
78      }
79      else{
80          store((byteAddress/4), value, memError);
81          (*memError) = FALSE;
82      }
83   
84
85  }
86  #endif
87
88

メモリ.h:

1   #define MEMSIZE 1024     //1024 words of memory
2   #ifndef MEMORY_H
3   #define MEMORY_H
4 
5   unsigned int fetch(int address, bool * memError);
6   void store(int address, unsigned int value, bool * memError);
7   unsigned char getByte(int byteAddress, bool * memError);
8   void putByte(int byteAddress, unsigned char value, bool * memError);
9   void clearMemory();
10  unsigned int getWord(int byteAddress, bool * memError);
11  void putWord(int byteAddress, unsigned int value, bool * memError);
12  #endif 
4

1 に答える 1

0

その場合、配列を注意深く調べる必要があります。最も一般的なエラーは、(a) 長さが足りない、または (b) 文字列/配列がゼロ (null) で終了していると想定する関数を呼び出しているが、ゼロが追加されていないことです。 . C の文字列は、C 文字列関数が機能するように null で終了します。

いくつかのトラブルスポットの例...

47                 char addressString[3];
48                 for(j = 0; j < 3; j++){ //Creates char array of address on current line.
49                      addressString[j] = inputLine[j+4];
50                 }
51                 byteAddress = atoi(addressString); //Turns the array into an int to pass to putByte

入力行から に 3 バイトをコピーしていますaddressString。ただし、この配列には文字を保持するのに十分なスペースしかなく、null 終端はありません。そのため、後続のatoi呼び出しはネバー ネバー ランド (セグメンテーション違反の可能性) に入る可能性があります。

ここに、dataString文字の配列があります:

53                 unsigned char dataString[12];
54                 for(k = 0; k < 12; k++) {
55                      dataString[k] = (unsigned char)intLine[k+9];
56                 }
57 

ここでdataStringは、単一の文字であるかのように扱っています。

58                 unsigned char data = dataString;
59 
60                 if(checkLine(inputLine) == FALSE){
61                     printf("Error on line %d:\n",lineNumber);
62                     printf("%s\n",inputLine);
63                     return 0;
64                 }
65                 
66                 else{
67                     putByte(byteAddress, dataString, &memError);
68                 }

これは segfault を引き起こさないかもしれませんが、間違いなく正しくありません。

于 2014-03-24T16:32:38.057 に答える