MIPS Help. Exception error/bad address?

  • Thread starter Thread starter trouty323
  • Start date Start date
  • Tags Tags
    Mips
AI Thread Summary
The discussion revolves around a MIPS assembly code issue where the user is attempting to store hard-coded data in an array, find the largest number, and place that number at the end of the array. The user encounters an error related to memory access, specifically "Bad address in data/stack read." Suggestions include ensuring the base address is correct and initializing the index and maximum value registers properly to avoid using garbage values. Debugging techniques are recommended, such as using print statements to monitor register values. The conversation also highlights the importance of not hard-coding array sizes and suggests calculating the number of elements dynamically to prevent errors when modifying the array. The user ultimately resolves the issue, realizing the error was due to accidentally running the code multiple times, and discusses best practices like labeling arrays for better code readability and maintainability.
trouty323
Messages
23
Reaction score
0
Hello. My task here is to store hard-code data directly into an array, find the largest in the array, then put that number at the end of the array. My code that I have is below, but I am getting an error. The error is:

"Exception occurred at PC=0x0040003c"
"Bad address in data/stack read = 0x2002003c"

Any ideas?

Code:
.data
.word 7
.word 39
.word 42
.word 16
.word 15
.word 21
.word 3
.word 2
.word 37
.word 11
.word 32
.word 28
.word 40
.word 27
.word 20

.text

.globl main

main:

lui $s0, 0x1001		# base address
add $t0, $t0, $zero	# index count
add $t1, $t1, $zero	# max element, $t1 = 0
addi $t5, $t5, 15	# number of elements
add $t2, $t2, $s0	# offset plus base

Loop:

beq $t0, $t5, Exit	# branch if counter is equal to number of elements in array
lw $t3, 0($t2)		# reading first element
addi $t0, $t0, 1	# increment counter by 1
addi $t2, $t2, 4	# increment offset by 4
slt $t4, $t1, $t3	# $t4 = 1 if $t1 is less than $t3, otherwise $t4 = 0
beq $t4, $zero, Loop	# branch to loop if value in $t4 is equal to value in $zero
add $t1, $t3, $zero	# 

j Loop

Exit:

sw $t1, 0($t2)		# store highest back into array

li $v0, 10 		# syscall to terminate
syscall
 
Technology news on Phys.org
You're doing some things that seem questionable to me. I haven't programmed in MIPS, but I have a lot of experience in x86 assembly and some M68000 assembly.

1. lui $s0, 0x1001 # base address
Are you sure that's the right address?
2. add $t0, $t0, $zero # index count
You're adding 0 to $t0, and then storing the sum in $t0, which is likely to be whatever garbage value was already in $t0.
It might be better to do this:
andi $t0, $t0, 0
3. Same as above for $t1.

I have no idea what sort of development environment you are working in. Is there a debugger of some sort? I'm assuming that you're running some MIPS emulator on a PC. If you have a debugger, you could use it to single-step through your code, and see the actual values of the registers you're using.

If you don't have access to a debugger, you'll need to use the age-old technique of inserting print statements. For MIPS, this entails using syscall statements with the registers set up appropriately for what you're trying to print. For example, to print (display) an integer, do something like this:
Code:
  # display the integer value in int_value
  li $v0, 1
  la $a0, int_value
  syscall

I would do this in the loop, where you store a value from the array in $t3.
 
I'm not seeing the error you reported. Your code seems to be working fine, but it's hard to follow from your comments.

I changed the form a little bit in the data block, and to make it run more quickly, I have fewer elements in the array.

Code:
.data	
   .word 7, 39, 42, 16, 0xffff

.text

.globl main

main:

lui $s0, 0x1001		# base address
add $t0, $t0, $zero	# Initialize the array index, $t0
add $t1, $t1, $zero	# Store max element in $t1
addi $t5, $t5, 4	# Store the number of elements in $t5
add $t2, $t2, $s0	# Store address of first element in $t2

Loop:

beq $t0, $t5, Exit	# If index == number of elements in array, branch to Exit
lw $t3, 0($t2)		# Read the first element
addi $t0, $t0, 1	# increment counter by 1
addi $t2, $t2, 4	# increment offset by 4
slt $t4, $t1, $t3	# $t4 = 1 if $t1 is less than $t3, otherwise $t4 = 0
beq $t4, $zero, Loop	# branch to loop if value in $t4 is equal to value in $zero
add $t1, $t3, $zero	# Copy $t3 to $t1

j Loop

Exit:

sw $t1, 0($t2)		# store highest back into array

li $v0, 10 		# syscall to terminate
syscall
 
Yes, It did work after all. I think I was accidentally clicking run more than once, which was causing the error. It was a stupid mistake. Thanks for the tips!
 
Sure, you're welcome. One other thing I did but didn't show in the code I posted was to make a label for the array. Doing this means I don't have to hard-code the address of the array, which isn't very good practice.

Code:
.data	
array:   .word 7, 39, 42, 16, 0xffff

.text
    la $s0, array
   .
   .
   .

One of the other changes I made, besides working with a smaller array, was to add a "don't care" value at the end, 0xFFFF. Using your code, that's the value that gets overwritten by the largest of the values in the array proper.

A nicer way of doing this might be like so:
Code:
.data	
array:   .word 7, 39, 42, 16
max:    .word  0xffff # any value here is fine - it will be overwritten

I'm sure it's also possible to automate the counting of the array elements, instead of counting them by hand and loading $t5 with an immediate value.

The basic idea is this:
1) Calculate max - array. This gives you the number of bytes between the start of the array and max.
2) Divide that value by 4 by shifting left by two bits. That will give you the number of words in the array itself.

For example, suppose that the array has 8 elements, and the array starts at 0x00400100, and that max is at 0x00400120. The difference is 0x20, or 0010 0000 in binary. A left shift by two bits results in 0000 1000 in binary, or 8, the number of elements in the array. This is a much safer way to do things. If you hard-code the number of elements, and you add elements to the array but forget to change the line that stores the hard-coded array size, it will screw things up. If you let the computer count them, it will always get the right result when you add elements to the array or remove them from it.
 
Thread 'Is this public key encryption?'
I've tried to intuit public key encryption but never quite managed. But this seems to wrap it up in a bow. This seems to be a very elegant way of transmitting a message publicly that only the sender and receiver can decipher. Is this how PKE works? No, it cant be. In the above case, the requester knows the target's "secret" key - because they have his ID, and therefore knows his birthdate.
Thread 'Project Documentation'
Trying to package up a small bank account manager project that I have been tempering on for a while. One that is certainly worth something to me. Although I have created methods to whip up quick documents with all fields and properties. I would like something better to reference in order to express the mechanical functions. It is unclear to me about any standardized format for code documentation that exists. I have tried object orientated diagrams with shapes to try and express the...
Back
Top