Printing an array of char to a string in MIPS

Click For Summary
The MIPS code provided attempts to mimic a C function that prints a null-terminated string but encounters a "Memory address out of bounds" error due to two main issues. First, the character array is declared both globally and locally within the main function, leading to confusion about which array is being referenced. Second, the array is too small; declaring it as `char y[1]` only allocates space for one character, while a null-terminated string requires an additional byte for the null character. A suggested solution involves rewriting the code to properly allocate memory for the string and correctly handle the null termination, ensuring it runs without errors in MIPS simulators. Properly managing memory allocation and array declarations is crucial for successful execution.
-EquinoX-
Messages
561
Reaction score
1
I am trying to mimic the function below in MIPS:

extern void print_int(int x);
extern void print_string(char x[]);

char y[1];

void main(void) {
char y[1];
y[0] = 'a';
y[1] = '\0';
print_string(y);
}


and my MIPS code for the above C code is below

can someone tell me why when I try to run this in spim it fails. It generates this error:

Memory address out of bounds

As far as I know I am already passing the address of y, which is an array of char terminated by a null string at the end. But why this error? How do I fix this?


Code:
.text
	.globl main
	main:
			# Function Entry
	sw $ra,-20($sp)
	sw $fp,-24($sp)
	add  $fp, $zero, $sp
	subu $sp, $sp, 24
			# MOVE 
	add $t0,$zero,0
	sw  $t0,-8($fp)
			# MOVE 
	add $t0,$zero,97
	lw  $t1,-8($fp)
	add  $t2,$zero,-2
	add $t1,$t2,$t1
	add $t1,$fp,$t1
	sb  $t0,($t1)
			# MOVE 
	add $t0,$zero,1
	sw  $t0,-12($fp)
			# MOVE 
	add $t0,$zero,0
	lw  $t1,-12($fp)
	add  $t2,$zero,-2
	add $t1,$t2,$t1
	add $t1,$fp,$t1
	sb  $t0,($t1)
			# MOVE 
	lw  $t0,-4($fp)
	add  $t1,$zero,-2
	add $t0,$t0,$t1
	add $t0,$fp,$t0
	lb  $t1,($t0)
	sw $t1,-16($fp)
			# PARAM
	lw  $t0,-16($fp)
	sub $sp,$sp,4
	sw $t0, ($sp)
			# PARAM in REG0
	lw  $a0,-16($fp)
			# PARAM in REG1
	lw  $a1,-16($fp)
			# Function call
	jal print_string
	add $sp,$sp,4
			# Function Ends
	LABEL1:
			# Exit Sequence
	lw $ra,-20($fp)
	add  $sp, $zero, $fp
	lw $fp,-24($fp)
	jal $ra
 
print_int:
	li $v0,1
	lw $a0, 0($sp)
	syscall
	jr $ra
 
print_string:
	li $v0,4
	lw $a0, 0($sp)
	syscall
	jr $ra
 
Technology news on Phys.org
The OP hasn't been around for 9+ years, but maybe somebody else will get something out of my reply.
-EquinoX- said:
I am trying to mimic the function below in MIPS:

extern void print_int(int x);
extern void print_string(char x[]);

char y[1];

void main(void) {
char y[1];
y[0] = 'a';
y[1] = '\0';
print_string(y);
}
This code has two problems:
The char array is declared both outside of main() as well as inside it. Any references to y inside main apply to the local array, the one declared in main().
The array is too small. Declaring it as char y[1] allocates space for only one byte. For a C-type null-terminated string with N characters, the declaration should be char y[N+1]; to allow space for the terminating null character. Your assignment statement overwrites memory that doesn't belong to the y array.
-EquinoX- said:
and my MIPS code for the above C code is below

can someone tell me why when I try to run this in spim it fails. It generates this error:

Memory address out of bounds

As far as I know I am already passing the address of y, which is an array of char terminated by a null string at the end. But why this error? How do I fix this?
Code:
.text
    .globl main
    main:
            # Function Entry
    sw $ra,-20($sp)
    sw $fp,-24($sp)
    add  $fp, $zero, $sp
    subu $sp, $sp, 24
            # MOVE
    add $t0,$zero,0
    sw  $t0,-8($fp)
            # MOVE
    add $t0,$zero,97
    lw  $t1,-8($fp)
    add  $t2,$zero,-2
    add $t1,$t2,$t1
    add $t1,$fp,$t1
    sb  $t0,($t1)
            # MOVE
    add $t0,$zero,1
    sw  $t0,-12($fp)
            # MOVE
    add $t0,$zero,0
    lw  $t1,-12($fp)
    add  $t2,$zero,-2
    add $t1,$t2,$t1
    add $t1,$fp,$t1
    sb  $t0,($t1)
            # MOVE
    lw  $t0,-4($fp)
    add  $t1,$zero,-2
    add $t0,$t0,$t1
    add $t0,$fp,$t0
    lb  $t1,($t0)
    sw $t1,-16($fp)
            # PARAM
    lw  $t0,-16($fp)
    sub $sp,$sp,4
    sw $t0, ($sp)
            # PARAM in REG0
    lw  $a0,-16($fp)
            # PARAM in REG1
    lw  $a1,-16($fp)
            # Function call
    jal print_string
    add $sp,$sp,4
            # Function Ends
    LABEL1:
            # Exit Sequence
    lw $ra,-20($fp)
    add  $sp, $zero, $fp
    lw $fp,-24($fp)
    jal $ra

print_int:
    li $v0,1
    lw $a0, 0($sp)
    syscall
    jr $ra

print_string:
    li $v0,4
    lw $a0, 0($sp)
    syscall
    jr $ra
This is very difficult to follow, as what comments you have (e.g., #MOVE, #PARAM) don't give the reader a clear idea of what you are doing. Instead of trying to fix your code, I will rewrite it to more-or-less match what you were trying to do with the C code.
This code correctly displays the string in the user data segment, and will run with no errors in either QtSpim, the current incarnation of what used to be called SPIM, or in MARS, another MIPS simulator.
Code:
    .data
Str:    .asciiz "This is a string"

    .text
    .globl main
main:
    addi $sp, $sp, -4    # Allocate space on stack for string address
    la $a0, Str        # Load addr. of 1st char in string to $a0
    sw $a0, ($sp)        # Push string addr. onto stack
    jal print_string
    addi $sp, $sp, 4    # Restore stack to previous state

    li $v0, 10        # Terminate service
    syscall    
.end main         

print_string:
    li $v0, 4        # Code for print string service
    lw $a0, 0($sp)        # Load address from stack to $a0
    syscall
    jr $ra
To make this more interesting, the print_string sub could be implemented to iterate through the array, displaying one character per iteration.
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 4 ·
Replies
4
Views
7K
  • · Replies 1 ·
Replies
1
Views
10K
  • · Replies 4 ·
Replies
4
Views
1K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 5 ·
Replies
5
Views
10K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
8K
  • · Replies 4 ·
Replies
4
Views
5K
  • · Replies 4 ·
Replies
4
Views
21K
  • · Replies 1 ·
Replies
1
Views
8K