1,105,295 Community Members

Arithmetic Overflow error in array reverser (MIPS)

Member Avatar
eggshell5150
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

I'm about at my wits' end trying to figure this out. This is homework, so any hints would be appreciated. I was tasked with filling in a few blocks of code (these are denoted by comment lines with a number resting in the middle) involving function calls in MIPS. The program is supposed to read a specified number of integers (determined at run time by the first question), re-print them, then flip the order and print them again. It then asks if there is another case to enter, and exits following a negative response. Specifically, the error in question is occuring at line 327, but I have no idea what is causing it. Thanks!

Here's my code:

                    .text
                    .globl main
main:                   
#   int intArr[7];
#   int valsToDo;
#   char reply;
#   char vtdPrompt[] = "vals to do? ";
#   char entIntPrompt[] = "enter an int: ";
#   char adjMsg[] = " is bad, make it ";
#   char initLab[] = "initial:\n";
#   char flipLab[] = "flipped:\n";
#   char dmPrompt[] = "do more? ";
#   int i, j;
#################
# Register Usage:
#################
# $t0: register holder for a value
# $t1: i
# $t2: j
#################
                    addiu $sp, $sp, -109
                    jal DoStrInitCode       # "atypical" use of function to reduce clutter
#   do
#   {
begWBodyM1:
#      valsToDo = GetOneIntByVal(vtdPrompt);
                    li $a0, '\n'
                    li $v0, 11
                    syscall                 # '\n' to offset effects of syscall #12 drawback
                    move $a0, $sp
                    jal GetOneIntByVal
                    sw $v0, 77($sp)
#      ValidateInt(&valsToDo, 1, 7, adjMsg);
                    addi $a0, $sp, 77
                    li $a1, 1
                    li $a2, 7
                    addi $a3, $sp, 28
####################(4)####################
                    jal ValidateInt
#      for (i = valsToDo; i > 0; --i)
                    lw $t1, 77($sp)
                    j FTestM1
begFBodyM1:                 
#         if (i % 2) // i is odd
                    andi $t0, $t1, 0x00000001
                    beqz $t0, ElseI1
#            intArr[valsToDo - i] = GetOneIntByVal(entIntPrompt);
                    addi $a0, $sp, 13
                    jal GetOneIntByVal

                    lw $t0, 77($sp)
                    sub $t0, $t0, $t1
                    sll $t0, $t0, 2
                    lw $t3, 81($sp)
                    add $t0, $t3, $t0

                    move $t0, $v0
####################(8)####################

                    j endI1
#         else // i is even
ElseI1:
#            GetOneIntByAddr(intArr + valsToDo - i, entIntPrompt);
                    lw $a0, 77($sp)
                    sub $a0, $a0, $t1
                    sll $a0, $a0, 2
                    addi $a0, $a0, 81
                    add $a0, $a0, $sp
                    addi $a1, $sp, 13
                    jal GetOneIntByAddr
####################(7)####################                 
endI1:
                    addi $t1, $t1, -1
FTestM1:
                    bgtz $t1, begFBodyM1 
#      ShowIntArray(intArr, valsToDo, initLab);
                    addi $a0, $sp, 81
                    addi $a1, $sp, 77
                    addi $a2, $sp, 46
####################(3)####################
                    jal ShowIntArray

#      for (i = 0, j = valsToDo - 1; i < j; ++i, --j)
                    li $t1, 0
                    addi $t3, $sp, 77
                    addi $t2, $t3, -1
####################(3)####################
                    j FTestM2
begFBodyM2:
#         SwapTwoInts(intArr + i, intArr + j);
                    addi $a0, $sp, 81
                    sll $a0, $t1, 2         
                    add $a0, $a0, $sp
                    addi $a1, $sp, 81
                    sll $a1, $t2, 2
                    add $a1, $a1, $sp
####################(8)####################
                    jal SwapTwoInts

                    addi $t1, $t1, 1
                    addi $t2, $t2, -1
FTestM2:
                    blt $t1, $t2, begFBodyM2
#      ShowIntArray(intArr, valsToDo, flipLab);
                    addi $a0, $sp, 81
                    addi $a1, $sp, 77
                    addi $a2, $sp, 56
####################(3)####################
                    jal ShowIntArray

#      GetOneCharByAddr(&reply, dmPrompt);
                    addi $a0, $sp, 76
                    addi $a1, $sp, 66
####################(2)####################
                    jal GetOneCharByAddr
#   }
#   while (reply != 'n' && reply != 'N');
                    move $v1, $v0
####################(1)####################
                    li $t0, 'n'
                    beq $v1, $t0, endWhileM1
                    li $t0, 'N'
                    bne $v1, $t0, begWBodyM1
endWhileM1:                             # extra helper label added

#   return 0;
#}
                    addiu $sp, $sp, 109
                    li $v0, 10
                    syscall

################################################################################
#int GetOneIntByVal(const char prompt[])
#{
GetOneIntByVal:
#   int oneInt;
#   cout << prompt;
                    li $v0, 4
                    syscall
#   cin >> oneInt;
                    li $v0, 5
                    syscall
#   return oneInt;
#}
                    jr $ra

################################################################################
#void GetOneIntByAddr(int* intVarToPutInPtr, const char prompt[])
#{
GetOneIntByAddr:
#   cout << prompt;
                    move $t0, $a0       # $t0 has saved copy of $a0 as received
                    move $a0, $a1
                    li $v0, 4
                    syscall
#   cin >> *intVarToPutInPtr;
                    li $v0, 5
                    syscall
                    sw $v0, 0($t0)
#}
                    jr $ra

################################################################################
#void ValidateInt(int* givenIntPtr, int minInt, int maxInt, const char msg[])
#{
ValidateInt:
#################
# Register Usage:
#################
# $t0: copy of arg1 ($a0) as received
# $v1: value loaded from mem (*givenIntPtr)
#################
                    move $t0, $a0       # $t0 has saved copy of $a0 as received
#   if (*givenIntPtr < minInt) 
#   {
                    lw $v1, 0($t0)      # $v1 has *givenIntPtr
                    bge $v1, $a1, ElseVI1
#      cout << *givenIntPtr << msg << minInt << endl;
                    move $a0, $v1
                    li $v0, 1
                    syscall
                    move $a0, $a3
                    li $v0, 4
                    syscall
                    move $a0, $a1
                    li $v0, 1
                    syscall
                    li $a0, '\n'
                    li $v0, 11
                    syscall
#      *givenIntPtr = minInt;
                    sw $a1, 0($t0)
                    j endIfVI1
#   }
#   else 
#   {
ElseVI1:
#      if (*givenIntPtr > maxInt) 
#      {
                    ble $v1, $a2, endIfVI2
#         cout << *givenIntPtr << msg << maxInt << endl;
                    move $a0, $v1
                    li $v0, 1
                    syscall
                    move $a0, $a3
                    li $v0, 4
                    syscall
                    move $a0, $a2
                    li $v0, 1
                    syscall
                    li $a0, '\n'
                    li $v0, 11
                    syscall
#         *givenIntPtr = maxInt;
                    sw $a2, 0($t0)
#      }
endIfVI2:
#   }
endIfVI1:
#}
                    jr $ra

################################################################################
#void ShowIntArray(const int array[], int size, const char label[])
#{
ShowIntArray:
#################
# Register Usage:
#################
# $t0: copy of arg1 ($a0) as received
# $a3: k
# $v1: value loaded from mem (*givenIntPtr)
#################
                    move $t0, $a0       # $t0 has saved copy of $a0 as received
#   cout << label;
                    move $a0, $a2
                    li $v0, 4
                    syscall
#   int k = size;
                    move $a3, $a1
                    j WTestSIA
#   while (k > 0)
#   {
begWBodySIA:
#      cout << array[size - k] << ' ';
                    sub $v1, $a1, $a3   # $v1 gets (size - k)
                    sll $v1, $v1, 2     # $v1 now has 4*(size - k)
                    add $v1, $v1, $t0   # $v1 now has &array[size - k]
                    lw $a0, 0($v1)      # $a0 has array[size - k]
                    li $v0, 1
                    syscall
                    li $a0, ' '
                    li $v0, 11
                    syscall
#      --k;
                    addi $a3, $a3, -1
#   }
WTestSIA:
                    bgtz $a3, begWBodySIA
#   cout << endl;
                    li $a0, '\n'
                    li $v0, 11
                    syscall
#}
                    jr $ra

################################################################################
#void SwapTwoInts(int* intPtr1, int* intPtr2)
#{
SwapTwoInts:
#################
# Register Usage:
#################
# (fill in where applicable)
#################
#   int temp = *intPtr1;
#  *intPtr1 = *intPtr2;
#   *intPtr2 = temp;

####################(4)####################
                    move $t5, $a0
                    move $t6, $a0
                    move $t5, $v1
                    move $t6, $v0                   
#
                    jr $ra

################################################################################
#void GetOneCharByAddr(char* charVarToPutInPtr, const char prompt[])
#{
GetOneCharByAddr:
#################
# Register Usage:
#################
# (fill in where applicable)
#################
#   cout << prompt;
#   cin >> *charVarToPutInPtr;

####################(7)####################
                    move $t0, $a0
                    move $a0, $a1
                    li $v0, 4
                    syscall

                    li $v0, 5
                    syscall
                    sw $v0, 0($t0)
#}
                    jr $ra

################################################################################
DoStrInitCode:  
# not part of given C++ program
# "unusual" use of function to move "bulky & boring" string-initializing code 
# off of main stage
#################
# Register Usage:
#################
# $t0: register holder for a value
#################
                    li $t0, '\0'
                    sb $t0, 27($sp)
                    li $t0, ' '
                    sb $t0, 26($sp)
                    li $t0, ':'
                    sb $t0, 25($sp)
                    li $t0, 't'
                    sb $t0, 24($sp)
                    li $t0, 'n'
                    sb $t0, 23($sp)
                    li $t0, 'i'
                    sb $t0, 22($sp)
                    li $t0, ' '
                    sb $t0, 21($sp)
                    li $t0, 'n'
                    sb $t0, 20($sp)
                    li $t0, 'a'
                    sb $t0, 19($sp)
                    li $t0, ' '
                    sb $t0, 18($sp)
                    li $t0, 'r'
                    sb $t0, 17($sp)
                    li $t0, 'e'
                    sb $t0, 16($sp)
                    li $t0, 't'
                    sb $t0, 15($sp)
                    li $t0, 'n'
                    sb $t0, 14($sp)
                    li $t0, 'e'
                    sb $t0, 13($sp)
                    li $t0, '\0'
                    sb $t0, 12($sp)
                    li $t0, ' '
                    sb $t0, 11($sp)
                    li $t0, '?'
                    sb $t0, 10($sp)
                    li $t0, 'o'
                    sb $t0, 9($sp)
                    li $t0, 'd'
                    sb $t0, 8($sp)
                    li $t0, ' '
                    sb $t0, 7($sp)
                    li $t0, 'o'
                    sb $t0, 6($sp)
                    li $t0, 't'
                    sb $t0, 5($sp)
                    li $t0, ' '
                    sb $t0, 4($sp)
                    li $t0, 's'
                    sb $t0, 3($sp)
                    li $t0, 'l'
                    sb $t0, 2($sp)
                    li $t0, 'a'
                    sb $t0, 1($sp)
                    li $t0, 'v'
                    sb $t0, 0($sp)
                    li $t0, '\0'
                    sb $t0, 55($sp)
                    li $t0, '\n'
                    sb $t0, 54($sp)
                    li $t0, ':'
                    sb $t0, 53($sp)
                    li $t0, 'l'
                    sb $t0, 52($sp)
                    li $t0, 'a'
                    sb $t0, 51($sp)
                    li $t0, 'i'
                    sb $t0, 50($sp)
                    li $t0, 't'
                    sb $t0, 49($sp)
                    li $t0, 'i'
                    sb $t0, 48($sp)
                    li $t0, 'n'
                    sb $t0, 47($sp)
                    li $t0, 'i'
                    sb $t0, 46($sp)
                    li $t0, '\0'
                    sb $t0, 45($sp)
                    li $t0, ' '
                    sb $t0, 44($sp)
                    li $t0, 't'
                    sb $t0, 43($sp)
                    li $t0, 'i'
                    sb $t0, 42($sp)
                    li $t0, ' '
                    sb $t0, 41($sp)
                    li $t0, 'e'
                    sb $t0, 40($sp)
                    li $t0, 'k'
                    sb $t0, 39($sp)
                    li $t0, 'a'
                    sb $t0, 38($sp)
                    li $t0, 'm'
                    sb $t0, 37($sp)
                    li $t0, ' '
                    sb $t0, 36($sp)
                    li $t0, ','
                    sb $t0, 35($sp)
                    li $t0, 'd'
                    sb $t0, 34($sp)
                    li $t0, 'a'
                    sb $t0, 33($sp)
                    li $t0, 'b'
                    sb $t0, 32($sp)
                    li $t0, ' '
                    sb $t0, 31($sp)
                    li $t0, 's'
                    sb $t0, 30($sp)
                    li $t0, 'i'
                    sb $t0, 29($sp)
                    li $t0, ' '
                    sb $t0, 28($sp)
                    li $t0, '\0'
                    sb $t0, 75($sp)
                    li $t0, ' '
                    sb $t0, 74($sp)
                    li $t0, '?'
                    sb $t0, 73($sp)
                    li $t0, 'e'
                    sb $t0, 72($sp)
                    li $t0, 'r'
                    sb $t0, 71($sp)
                    li $t0, 'o'
                    sb $t0, 70($sp)
                    li $t0, 'm'
                    sb $t0, 69($sp)
                    li $t0, ' '
                    sb $t0, 68($sp)
                    li $t0, 'o'
                    sb $t0, 67($sp)
                    li $t0, 'd'
                    sb $t0, 66($sp)
                    li $t0, '\0'
                    sb $t0, 65($sp)
                    li $t0, '\n'
                    sb $t0, 64($sp)
                    li $t0, ':'
                    sb $t0, 63($sp)
                    li $t0, 'd'
                    sb $t0, 62($sp)
                    li $t0, 'e'
                    sb $t0, 61($sp)
                    li $t0, 'p'
                    sb $t0, 60($sp)
                    li $t0, 'p'
                    sb $t0, 59($sp)
                    li $t0, 'i'
                    sb $t0, 58($sp)
                    li $t0, 'l'
                    sb $t0, 57($sp)
                    li $t0, 'f'
                    sb $t0, 56($sp)

                    jr $ra
Member Avatar
Schol-R-LEA
Nearly a Posting Virtuoso
1,384 posts since Oct 2010
Reputation Points: 635 [?]
Q&As Helped to Solve: 225 [?]
Skill Endorsements: 28 [?]
 
0
 

Why are you initializing the data this way? With most MIPS assemblers (including those for SPIM and MARS, as far as I know), you should be able to declare the string constants as, well, constants, like so:

                      .data
vtdPrompt:    .asciiz "vals to do? "
entIntPrompt: .asciiz "enter an int: "
adjMsg:       .asciiz " is bad, make it "
# and so on...

It is hard to imagine an assembler that didn't allow static data initialization... It's a fairly basic and fundamental procedure that it wouldn't make sense not to support it. Even if there were some overriding reason to have the data on the stack rather than in the .data section, it would be far easier to simply initialize it in the global .rodata and then copy it to the stack in a loop.

Member Avatar
eggshell5150
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

The homework is an exercise in doing everything locally. If I was allowed to rewrite it with global strings, I definitely would. Right now I just have to play ball and attempt to make this thing run. The blocks of code that I had to add are at lines 38, 58, 71, 80, 97, 108, 114, 119, 280, and 300, situated just above the comment line containing a number. The suggested number of lines to add correspond to the numbers in the comment lines in parentheses. Everything else is what was given to me by my instructor, and I was told not to change anything.

In any case, thank you for your time. Any help is appreciated.

Member Avatar
Schol-R-LEA
Nearly a Posting Virtuoso
1,384 posts since Oct 2010
Reputation Points: 635 [?]
Q&As Helped to Solve: 225 [?]
Skill Endorsements: 28 [?]
 
0
 

So, then, the problem lies in the code provided to you by your professor? Odd, though hardly impossible, I suppose. The lines in question are, if I am not mistaken,

                li $t0, ' '
                sb $t0, 26($sp)
                li $t0, ':'      
                sb $t0, 25($sp)    # error occurs here
                li $t0, 't'
                sb $t0, 24($sp)

It's hard to see how this could possibly cause an arithmetic overflow, however. Are you certain that the error is on line 327?

BTW, could you let us know which MIPS simulator and assemblwer you're using? It could be relevant in trying to help track down the problem.

Member Avatar
eggshell5150
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

My mistake, 327 is the line it falls on with a doc block. 245 is what I meant to put in the original post. The error triggers when the printing fuction for the integer array is called. Sorry about that.

Lines in question:

#    cout << array[size - k] << ' ';
                sub $v1, $a1, $a3   # $v1 gets (size - k)
                sll $v1, $v1, 2     # $v1 now has 4*(size - k)
                add $v1, $v1, $t0   # $v1 now has &array[size - k] <-- 248
                lw $a0, 0($v1)      # $a0 has array[size - k]
                li $v0, 1
                syscall
                li $a0, ' '
                li $v0, 11
                syscall
#      --k;
                addi $a3, $a3, -1
Member Avatar
eggshell5150
Newbie Poster
4 posts since Nov 2012
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Also, the assembler I'm using is Mars 4.2

You
This article has been dead for over three months: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: