简体   繁体   中英

Why isn't my MIPS program loading values from memory?

I'm working on a program that reverses a string place.

But I've run into some trouble.

The program works by looping the through the string once to get the length of the string.

Once found another loop begins, swapping characters from the back and front by saving the values in temp registers then stores into the byte the other value was located in.

Then the address of the beginning of the string is incremented and the end is decremented. This is done until a temp register which is also incremented in the loop is equal to half the length of the string.

But for some reason when I step the through the program it doesn't store the values of the characters into the register during the second loop.

Would anyone no why this is happening and how I can fix this?

Thank you.

.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

When you step through the program, you should verify all your assumptions, especially if you notice some problem, like values of letters not loading properly.

In your case (I did run it in MARS), just ahead of label swap: the registers contain:

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

While the msg symbol value is 0x10010000 . That one is in t1 only, but you use t5, t6 to load values of string, t5 is pointing at the zero terminator of msg , t6 is way off. So "some reason" is that you don't read the memory you did want, but instead memory beyond.

Judging by the comments in code, you used t0 instead of t1 in the "strlen", and you expected the t0 to retain the original msg address (but instead the t1 retains it, the t0 points to the zero terminator of msg ).

Also your code would fail for empty string, as you do some initial lb but don't test it, then you start checking for zero since second byte of string.

Overall you may often try to clean up your first idea a bit, and simplify it a bit, in this particular task you can do everything just with the pointers to the string, no need to calculate length/half_length as integers:

.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

(used few pseudo instructions, while your original source looks like you are trying to avoid them, but you still had few inaccurate ones, which must have got adjusted by assembler any way, like add $t0,$t0,1 -> addi )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM