2017-09-23 14 views
0

この割り当てでは、ユーザが入力した値0〜50に基づいてサイズnの配列を作成する必要があります。これまでのところ、これは以下の通りです。質問全体についてアドバイスがある場合は、それも非常に役に立つでしょう。ユーザ入力nからサイズnの配列を作成する

a)ユーザに0〜50の整数を入力するように要求します。ユーザが0を入力すると、プログラムは停止します。

b)そうでなければ、プログラムは入力値までの数値をメモリ内のワードの配列に格納する。すなわち、0からNまでの値で配列を初期化する。ここでNはユーザが入力した値である。

c)プログラムは、メインメモリからロードして合計したアレイの全項目の値を加算し(Nまで)、次にそれらを加算してメッセージの合計を出力します。 0〜Nは: "です。たとえば、ユーザが5を入力として与えた場合、プログラムは「0から5までの整数の合計は15です」と出力します。

シラバスに指定されているzipファイルとして、あなたの作品を期日までにeラーニングに送信してください。

.data 
userPrompt : .asciiz "enter in an integer from zero to fifty " 
zeroMessage : .asciiz " you have entered a zero , the program will close " 
incorrectEntry : .asciiz " you have entered in a value greater than 50 , 
this is an incorrect value" 

InputVal : .word 

upperLim : .word 50 

Array : .space InputVal 



.text 

main: 
    addi $t7 , $zero , 50 

    li $v0, 4 # load for printing of strings 
    la $a0, userPrompt 
    syscall 

# take in user input and move the read in number to a temp 
    li $v0, 5 
    la $t0 , InputVal 
    syscall 


    # Store int A into memory 
    move $t0 , $v0 
    beq $t0 , $0 , numbersEqual 


    la $t1 , upperLim 

    li $v0 , 1 
    move $a0 , $t1 
    syscall 


    slt $t3 ,$t0 , $t1 
    sw $t0 , InputVal 

    #beq $t3 , $0 , ELSE 





ELSE : 
    li $v0 , 4 
    la $a0 , incorrectEntry 
    syscall 
    li $v0 , 10 
    syscall 


numbersEqual: 

    li $v0 , 4 
    la $a0 , zeroMessage 
    syscall 
    li $v0 , 10 
    syscall 
+1

サイズNの配列に0からNまでの値を格納することはできません。N = 2で試してみましょう:今はサイズ2の配列{[..]、[..]} ..その中に値0,1,2を入れます(圧縮スキームなし)。できません。 N + 1サイズの配列が必要です。 – Ped7g

答えて

1

アセンブリ言語はマシンコードのシンボリック言語であり、マシンコードはCPUが実行できるものです。

ソースをコンパイルするためにアセンブラを実行すると、マシンコードが取得されます。これは最終的なものです。次に、そのマシンコードを実行します。 .word 0x12345678

は、CPUの命令ではなく、あなたのアセンブラのディレクティブは、それはマシンコードのその場所でメモリの全体wordを確保するためにそれを伝え、そこ0x12345678の店舗値。私は値がない.wordが少なくとも1つの単語を予約するかどうかわからない、確かにInputVal: .word 0を行う必要があります。最終的なマシンコードに

シンボルInputVal(としてアセンブラに知られたいくつかのアドレス、でword値を構成するそれぞれの値を持つものだけ4つのバイトが存在するであろう、それはCPUの命令ではない、いかなる「.word」が存在しませんこのテキスト形式のマシンコードの一部でもなく、このメモリアドレスを使用する命令には数値としてエンコードされた適切なアドレスのみがあり、実行可能バイナリには、実行前にマシンコードをターゲットメモリにロードする)。

これは明白であるように聞こえるかもしれませんが、違いが理解でき、CPUがマシンコードを実行しているときに利用可能なものと、アセンブラでコンパイル中に利用できるもの(コードはまだ実行されていません) 。 InputValはメモリアドレスのシンボルなので、

Array : .space InputValは望みどおりに機能しません。したがって、指示文.spaceは、bazillionバイト(メモリアドレスの値はInputVal)を予約するか、コンパイルが失敗する可能性が高くなります。あなたが望むのはInputValのメモリの内容ですが、コードが実行されなかったため、まだ知られていません。ユーザーは何も入力していないので、それは単なるアセンブリステップです。値がわからないので、あなたはArray: .space 0と書くことができます。しかし、それはスペースを予約しません。

ダイナミックメモリ割り当てを掘り下げたいのでなければ、そのような状況を解決するための簡単なトリックがありますが、これは特定の場合に有効です。タスクを読むと、Nは入力値が0〜50のときにのみ有効です(ユーザーエラーで終了できます)。最大N = 50の場合は、51個の値の配列が必要です。さらに多くの値を必要としません。

だから、あなたは、単に実行して(実行時に)すべての動的メモリ割り当てを避けることができます。

 .align 4 # make sure the reserved space is word-aligned 
Array: .space (51*4) 

これは記号で、あなたのマシンコード用データ領域にメモリの204バイト(51ワード)を予約しますArrayは、その最初のバイトを指しています。

これで、メモリーが予約され、値をそこに格納して使用できます。ランタイム中に心を変えて52ワードのメモリを使いたいなら、あなたはそのようなコードで運が悪いです。次に、動的割り当てを記述するか、コンパイル時にハードサイズの固定バッファをインクリメントする必要があります。

また、あなたのコードは、Arrayの中では常に51ワードしか使用できないため、入力したN + 1個の値だけを使用するのは自分のコードに任されています。ユーザーがN = 5を入力した場合は、残りの予約語を無視して6ワード(24バイト)を超えて作業する必要があります。

だからあなたのコード内の各ループはNはコンパイル時に知られていない実行時にユーザーが入力した値(あなたがそれを必要なときに、あなたがそれにアクセスできるように、InputVal確保したメモリに格納し)、あるfor (i = 0; i <= N; ++i) Array[i] = i;、のようになります。

関連する問題