2017-04-23 14 views
0

私は、MIPSコードをCに変換する必要がある代入に取り組んでいます(MIPSを知らなくてもこの問題を理解するのは簡単ですが、私はCで書いたコードを与えてください)。私は先生に連絡することができません。なぜなら、私たちは巨大なクラスであり、毎日十分な電子メールを受け取っていることを知っています。インデックスの代わりにポインタを使って配列を更新する

text1とtext2の各文字のasciiコードをlist1とlist2にコピーして、指定された関数で印刷できるようにするために、関数copycodes()を使用しようとしています。

私は基本的に完了していますが、うまくいくように思えますが、セグメンテーションフォールト(コアダンプ) - エラー、または2回だけループしますがリストから何も印刷しません。私は自分のコードと小さなものを変更し続けるが、私は一日中見てきたし、私の知識に欠陥がある場所を見つけることができないようだ。

プログラムは、機能copycodes()、function work()、およびpublic変数を除いて、先生が作成しました。すべてのコメントは(mipsコードでも)出現していますが、私も書いています。

前述のように、ソリューションの実装方法を表すMIPSコードも提供されました。このコードは、以下のコードのそれぞれの場所にコメントとして含まれています。私はMIPSコードに近づこうとしました。なぜなら、copycodes()の変数はアセンブリコードで使用されるレジスタの名前を持っています。ここで

は、私はそれを行っている方法です。

#include <stdio.h> 

//Assembly code: 
/* 
.data 


text1: .asciiz "This is a string." 
text2: .asciiz "Yet another thing." 

.align 2 
list1: .space 80 
list2: .space 80 
count: .word 0  
*/ 

//C translation: 

char* text1 = "This is a string."; 
char* text2 = "Yet another thing."; 


//int* list1; 
//int* list2; 
int list1 [80]; //Still passes the pointer of list1[0] to copycodes 
int list2 [80]; 

int count = 0; 


void printlist(const int* lst){ 
    printf("ASCII codes and corresponding characters.\n"); 
    while(*lst != 0){ 
    printf("0x%03X '%c' ", *lst, (char)*lst); 
    lst++; 
    } 
    printf("\n"); 
} 

void endian_proof(const char* c){ 
    printf("\nEndian experiment: 0x%02x,0x%02x,0x%02x,0x%02x\n", 
     (int)*c,(int)*(c+1), (int)*(c+2), (int)*(c+3)); 

} 




//Assembly code: 
/* 
copycodes: 
loop: 

    # a0 is text (.asciiz) 
    # a1 is list (.space) 
    # a2 is count (.word) 

    lb $t0,0($a0) # byte t0 = from a0 (text1/text2) 
    beq $t0,$0,done # branch done if (t0 == 0) 
    sw $t0,0($a1) # else word t0 = a1 (list1/list2) 

    addi $a0,$a0,1 # a0++ 
    addi $a1,$a1,4 # a1+4 

    lw  $t1,0($a2) # load word from a2 into t1 
    addi $t1,$t1,1 # increment t1 by 1 
    sw  $t1,0($a2) # store word from t1 to a2 
    j  loop  # jump to top 
done: 
    jr $ra 
*/ 

void copycodes(char* a0, int* a1, int* a2){ 


    char t0 = *a0; //load byte from where a0 is pointing into t0) 

    while(t0 != 0) //until end of string 
    { 

     //sw  $t0,0($a1)  // else word t0 = a1 (list1/list2) 

     //t0 = *a1; 
     *a1 = t0; //store word from t0 to where a1 is pointing) 



     //addi  $a0,$a0,1  // a0++ 
     //addi  $a1,$a1,4  // a1+4 

     a0++;  //increments pointer of text (a0) 
     a1 += 4; //increments pointer of list (a1) (in the mips code this is incremented by 4) 


     //lw  $t1,0($a2)  // load word from t1 into a2 
     //addi  $t1,$t1,1  // increment t1 by 1 
     //sw  $t1,0($a2)  // store word from t1 to a2 

     int countValue = *a2; //set countValue equal to value at pointer a2 
     countValue++;   //increment counter 
     *a2 = countValue;  // Set counter (at register a2) to the incremented value 

    } 


} 
void work(){ 

    copycodes(text1,list1,&count); 
    copycodes(text2,list2,&count); 

} 
int main(void){ 
    work(); 

    printf("\nlist1: "); 
    printlist(list1); //[20]); 
    printf("\nlist2: "); 
    printlist(list2); //); 
    printf("\nCount = %d\n", count); 

    endian_proof((char*) &count); 
} 

私は、このようなHomework: Making an array using pointers と同様の質問を見てきました。しかし、彼らは基本的にポインタについて同じことをやっているかのように、それは私に見えますか?私はしばらくの間、私の問題は私がa0とa1をインクリメントしていく量だと考えましたが、この問題を説明するanythigはまだ見つかりませんでした。

編集:

リスト1:ASCIIコードとそれに対応する文字 私は、所望の出力があることを追加しaswellかもしれません。 0x072 '' 0x069 '' 0x069 '' 0x069 '' 0x069 '' 0x073 '' 0x073 '' 0x020 '' 0x020 '' '0x07' '私' 0x06E 'n' 0x067 'g' 0x02E '。'

list2:ASCIIコードとそれに対応する文字。 0x072 'e' 0x074 't' 0x020 '' 0x061 '' 0x06E 'n' 0x06F 'o' 0x074 't' 0x068 'h' 0x065 'e' 0x072 'r' 0x020 '' 0x074 't' 0x068 'h' 0x069 'i' 0x06E 'n' 0x067 'g' 0x02E '。' =カウント35

エンディアン実験:メルポメネとドミトリ問題を見つけるためにする0x23,0x00,0x00,0x00

+3

'のA1 + = 4;' 'A1 + = 1であるべきです。'。 – melpomene

+3

't0'は' while'ループ内で更新する必要があります。そうでないと、常に同じ文字列(文字列の最初の文字)になります。あるいは、代わりに '* a0'を使用してください。 – Dmitri

+0

@melpomeneしかし、それは 'addi $ a1、$ a1,4 // a1 + 4'と言っています。どういう意味ですか? – synchronizer

答えて

0

多くの感謝!

私は本当にa1を間違ってインクリメントしていましたが、whileループ内でt0を更新することも忘れていました。私は完全にt0なしの解決策に終わった。ここ

更新関数である:

void copycodes(char* a0, int* a1, int* a2){ 
 

 

 
    //char t0 = *a0; //load byte from where a0 is pointing into t0) 
 

 
    while(*a0 != 0) //until end of string 
 
    { 
 

 
     //sw  $t0,0($a1)  // else word t0 = a1 (list1/list2) 
 

 
     //t0 = *a0; 
 
     *a1 = *a0; //store word from t0 to where a1 is pointing) 
 

 

 

 
     //addi  $a0,$a0,1  // a0++ 
 
     //addi  $a1,$a1,4  // a1+4 
 

 
     a0++;  //increments pointer of text (a0) 
 
     a1++; //increments pointer of list (a1) (in the mips code this is incremented by 4) 
 

 

 
     //lw  $t1,0($a2)  // load word from t1 into a2 
 
     //addi  $t1,$t1,1  // increment t1 by 1 
 
     //sw  $t1,0($a2)  // store word from t1 to a2 
 

 
     int countValue = *a2; //set countValue equal to value at pointer a2 
 
     countValue++;   //increment counter 
 
     *a2 = countValue;  // Set counter (at register a2) to the incremented value 
 

 
    } 
 

 

 
}

+1

意味のある変数名を使用すると、コードを理解するのに役立ちます。おそらく 'void copycodes(const char * a0_text、int * a1_list、int * a2_count)'? – chux

関連する問題