Printing an array of char to a string in MIPS

  • Thread starter -EquinoX-
  • Start date
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
 
32,344
4,130
The OP hasn't been around for 9+ years, but maybe somebody else will get something out of my reply.
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.
 

Want to reply to this thread?

"Printing an array of char to a string in MIPS" You must log in or register to reply here.

Physics Forums Values

We Value Quality
• Topics based on mainstream science
• Proper English grammar and spelling
We Value Civility
• Positive and compassionate attitudes
• Patience while debating
We Value Productivity
• Disciplined to remain on-topic
• Recognition of own weaknesses
• Solo and co-op problem solving
Top