2017-11-03 10 views
0

私は文字列の場所を逆にするプログラムに取り組んでいます。私のMIPSプログラムがメモリから値を読み込んでいないのはなぜですか?

しかし、私はいくつかの問題に遭遇しました。

プログラムは、文字列の長さを取得するために文字列を1回ループして動作します。

は一度別のループが、他の値が中に位置していたバイトに保存し、その後一時レジスタの値を保存することで、背面と正面から文字を交換、始まりました。

そして、文字列の先頭のアドレスですインクリメントされ、終了がデクリメントされる。これは、ループ内でインクリメントされる一時レジスタが文字列の長さの半分に等しくなるまで行われます。

しかし何らかの理由で私がプログラムをステップ実行すると、2番目のループの間に文字の値がレジスタに格納されません。

これはどうして私はこれを修正することができます誰もなぜでしょうか?

ありがとうございます。あなたがプログラムをステップ実行すると

.data 
msg: .asciiz "Hello World" 
nline: .asciiz "\n" 
.globl main 


.text 
#t0 address location 
#t1 address location used to increment and find \0 
#t2 value stored in addres location of t1 
#t3 stores length of string 
main: 
    la $t0,msg #load address location 

    add $t1,$t0,$zero #loads address location for use in loop 
    lb $t2,0($t1) #loads value found at address in t1 

    add $t3,$zero,$zero #set length to 0 


    len: #increments value that determines length and memory location of current character 
    addi $t3,$t3,1 
    add $t0,$t0,1 
    #add $a0,$zero,$t3 
    #li $v0,1 
    #syscall 
    lb $t2,0($t0) 

    bne $t2,$zero,len #loops back to len if null character is not found 


    srl $t4,$t3,1 


    add $t5,$t0,$zero 
    add $t6,$t3,$t0 

    add $t9,$zero,$zero 


    swap: 
    lb $t7,0($t5) 
    lb $t8,0($t6) 

    sb $t8,0($t6) 
    sb $t7,0($t5) 

    addi $t5,$t5,1 
    sub $t6,$t6,1 
    addi $t9,$t9,1 

    bne $t4,$t9,swap 


    li $v0,10 
    syscall 

答えて

0

することは、あなたは、文字の値が適切にロードしないように、あなたはいくつかの問題に気づく場合は特に、すべてのあなたの仮定を確認する必要があります。直前のラベルのレジスタが含まれているswap:あなたの場合

(私はMARSでそれを実行しなかった)、:

t0 0x1001000b 
t1 0x10010000 
t2 0 
t3 11 
t4 5 
t5 0x1001000b 
t6 0x10010016 

msgシンボル値が0x10010000ですが。それはt1にのみありますが、t5, t6を使用して文字列の値をロードすると、t5はゼロターミネーターmsgを指しています。t6はオフです。だから"何らかの理由"は、あなたが望むメモリを読まず、代わりにメモリを読んでいるということです。

は、コード内のコメントから判断するには、「STRLEN」にt0代わりのt1を使用し、元のmsgアドレスを保持するt0を期待(代わりt1は、それを保持するのゼロターミネータへt0ポイントmsg)。 のように、コードは空の文字列には失敗しますが、テストしないと、文字列の2番目のバイト以降にゼロをチェックし始めます。

全体として、最初のアイデアを少しきれいにして単純化しようとすることがよくあります。この特定のタスクでは、文字列へのポインタだけですべてを行うことができ、長さ/

.data 
msg: .asciiz "Hello World" 

.text 
.globl main 
main: 
    la $t0,msg  # t0 = string address 
    add $t1,$t0,$zero # t1 = string address for "strlen" 

len: # find zero terminator of string 
    lb $t2,($t1)  # t2 = letter from string 
    addi $t1,$t1,1  # advance string pointer 
    bne $t2,$zero,len # loop back to len if null character is not found 

    # t0 = string address, t1 = points 1 byte after the zero terminator 
    addi $t1,$t1,-2  # adjust t1 to point to last character 
    # validate that t0 < t1 (will not for empty or one letter strings) 
    bgeu $t0,$t1,too_short_to_reverse # sltu+beq 

swap: 
    lb $t2,0($t0)  # swap letters at t0/t1 positions 
    lb $t3,0($t1) 
    sb $t2,0($t1) 
    sb $t3,0($t0) 
    addi $t0,$t0,1  # adjust pointers 
    addi $t1,$t1,-1 
    blt $t0,$t1,swap # while t0 < t1 keep swapping letters 
too_short_to_reverse: 
    # done, string is reversed 

    # debug output of string to see it reversed 
    li $v0,4 
    la $a0,msg 
    syscall 

    li $v0,10   # exit syscall 
    syscall 

(あなたがそれらを避けるためにしようとしているようなあなたのオリジナルのソースが見えている間、いくつかの疑似命令を使用していますが、まだadd $t0,$t0,1 -> addiのように、アセンブラによってどのような方法を調整持っている必要がありますいくつかの不正確なものを、持っていた)

+0

うわー、私はそれらのすべてのミスを逃したとは信じられません。 Welp、私はまだ多くのことを学びました。ご協力ありがとうございます。 – user2883202

関連する問題