The MIPS assembly code generated by mips-gcc almost, but doesn't quite, run on the Mars MIPS simulator. For example:
The compiler generates "j $31" instead of "jr $31"
The compiler puts .align directives in the text segment, which Mars does not allow.
In addition, the generated assembly is not quite set up so that it will start and stop properly (i.e., no sycall 10 at the end).
These problems are all appear to be easily fixable with a simply script; but, before I re-invent the wheel, I was wondering:
(1) Are there any gcc flags that will make some of these problems go away?
(2) Does anybody know of an existing program that will fix up the mips-gcc output so that it will run on Mars?
(FWIW, I see the same behavior on both gcc 3.3.6 and 4.6.1.)
Are there any gcc flags that will make some of these problems go away?
Short answer is no. Mars uses custom system calls and is very different in calling conventions.
Does anybody know of an existing program that will fix up the mips-gcc output so that it will run on Mars?
I don't know of any automated way to convert it. You can do it only manually. I have done it actually.
Roughly, these are the steps I followed:
0. Use GobBolt compiler explorer to get a beatified raw assembly of your code. They don't use specific gcc options to get this beatified view according to this, so I'm not mentioning any gcc command, but you can set up a local copy of it.
Replace all the syscalls and their calling conventions according to this : https://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html
Replace/add the required segment labels (such as .text, .data etc.) along with their required data.
If you have a main function (label) add j main after .text.
(4. Optionally, you can rename the registers to be more readable because as Peter Cordes mentioned in the comments, gcc for mips doesn't support the argument -mregnames)
This is an example I made, it lacks main cause it was intended as a library :
C code :
#include <stdio.h>
#include <stdlib.h>
typedef struct node Node;
struct node {
int data;
struct node *left;
struct node *right;
};
Node *new_node (int data) {
Node *ret = malloc (sizeof (Node)); ret->left = NULL;
ret->data = data;
ret->left = NULL;
ret->right = NULL;
return ret; }
void link (Node *parent, Node *left, Node *right) {
parent->left = left;
parent->right = right;
}
int depth (Node *root) {
if (root == NULL) {
return -1;
}
int left = depth (root->left);
int right = depth (root->right);
return 1 + (left > right? left : right);
}
int even_level_max (Node *root, int level) {
if (root == NULL) {
return 0x80000000;
}
int left = even_level_max(root->left, level + 1);
int right = even_level_max (root->right, level + 1);
int greater = (left > right) ? left : right;
if (level % 2 == 0) {
return (greater > root->data)? greater : root->data;
} else {
return greater;
}
}
Godbolt code :
new_node:
addiu $sp,$sp,-40
sw $31,36($sp)
sw $fp,32($sp)
move $fp,$sp
sw $4,40($fp)
li $4,12 # 0xc
jal malloc
nop
sw $2,24($fp)
lw $2,24($fp)
nop
sw $0,4($2)
lw $2,24($fp)
lw $3,40($fp)
nop
sw $3,0($2)
lw $2,24($fp)
nop
sw $0,4($2)
lw $2,24($fp)
nop
sw $0,8($2)
lw $2,24($fp)
move $sp,$fp
lw $31,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
jr $31
nop
link:
addiu $sp,$sp,-8
sw $fp,4($sp)
move $fp,$sp
sw $4,8($fp)
sw $5,12($fp)
sw $6,16($fp)
lw $2,8($fp)
lw $3,12($fp)
nop
sw $3,4($2)
lw $2,8($fp)
lw $3,16($fp)
nop
sw $3,8($2)
nop
move $sp,$fp
lw $fp,4($sp)
addiu $sp,$sp,8
jr $31
nop
depth:
addiu $sp,$sp,-40
sw $31,36($sp)
sw $fp,32($sp)
move $fp,$sp
sw $4,40($fp)
lw $2,40($fp)
nop
bne $2,$0,$L5
nop
li $2,-1 # 0xffffffffffffffff
b $L6
nop
$L5:
lw $2,40($fp)
nop
lw $2,4($2)
nop
move $4,$2
jal depth
nop
sw $2,24($fp)
lw $2,40($fp)
nop
lw $2,8($2)
nop
move $4,$2
jal depth
nop
sw $2,28($fp)
lw $3,24($fp)
lw $2,28($fp)
nop
slt $4,$2,$3
beq $4,$0,$L7
nop
move $2,$3
$L7:
addiu $2,$2,1
$L6:
move $sp,$fp
lw $31,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
jr $31
nop
even_level_max:
addiu $sp,$sp,-48
sw $31,44($sp)
sw $fp,40($sp)
move $fp,$sp
sw $4,48($fp)
sw $5,52($fp)
lw $2,48($fp)
nop
bne $2,$0,$L9
nop
li $2,-2147483648 # 0xffffffff80000000
b $L10
nop
$L9:
lw $2,48($fp)
nop
lw $3,4($2)
lw $2,52($fp)
nop
addiu $2,$2,1
move $5,$2
move $4,$3
jal even_level_max
nop
sw $2,24($fp)
lw $2,48($fp)
nop
lw $3,8($2)
lw $2,52($fp)
nop
addiu $2,$2,1
move $5,$2
move $4,$3
jal even_level_max
nop
sw $2,28($fp)
lw $3,24($fp)
lw $2,28($fp)
nop
slt $4,$2,$3
beq $4,$0,$L11
nop
move $2,$3
$L11:
sw $2,32($fp)
lw $2,52($fp)
nop
andi $2,$2,0x1
bne $2,$0,$L12
nop
lw $2,48($fp)
nop
lw $3,0($2)
lw $2,32($fp)
nop
slt $4,$2,$3
beq $4,$0,$L10
nop
move $2,$3
b $L10
nop
$L12:
lw $2,32($fp)
$L10:
move $sp,$fp
lw $31,44($sp)
lw $fp,40($sp)
addiu $sp,$sp,48
jr $31
nop
Converted Mars code :
# Registers:
# a : store results
# t : temporaries
# s : saved
# k : kernel
.text:
j main
new_node: #Node *new_node (int data)
# prologue
addiu $sp,$sp,-40
sw $ra,36($sp)
sw $fp,32($sp)
move $fp,$sp
sw $a0,40($fp) # fp[40] = data
li $v0, 9
li $a0, 12
syscall
sw $v0,24($fp) # fp[24] = sbrk ( sizeof (Node = 12) )
lw $v0,24($fp)
lw $v1,40($fp) # data = fp[40]
sw $v1,0($v0) # ret[0] = data;
lw $v0,24($fp)
sw $zero,4($v0) # ret[4] = NULL;
lw $v0,24($fp)
sw $zero,8($v0) # ret[8] = NULL;
# epilogue
lw $v0,24($fp)
move $sp,$fp
lw $ra,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
jr $ra
nop
link: # int depth (Node *root)
# prologue
addiu $sp,$sp,-8
sw $fp,4($sp)
move $fp,$sp
#store arguments
sw $a0,8($fp)
sw $a1,12($fp)
sw $a2,16($fp)
#parent -> left = left;
lw $v0,8($fp)
lw $v1,12($fp)
sw $v1,4($v0)
sw $a1,4($a0)
# parent -> right = right
lw $v0,8($fp)
lw $v1,16($fp)
sw $v1,8($v0)
sw $a2,8($a0)
# epilogue
move $sp,$fp
lw $fp,4($sp)
addiu $sp,$sp,8
jr $ra
nop
depth: # int depth (Node *root)
# prologue
addiu $sp,$sp,-40
sw $ra,36($sp)
sw $fp,32($sp)
move $fp,$sp
sw $a0,40($fp) # fp[40] = root
lw $v0,40($fp)
bne $v0,$zero,L5
li $v0,-1
b L6 #if (root == NULL) return -1;
L5:
lw $v0,40($fp)
lw $v0,4($v0)
move $a0,$v0 # a0 = root -> left
jal depth # depth(a0)
sw $v0,24($fp) # fp[24] = depth(a0)
lw $v0,40($fp)
lw $v0,8($v0)
move $a0,$v0 # a0 = root -> right
jal depth # depth(a0)
sw $v0,28($fp) # fp[28] = depth(a0)
lw $v1,24($fp) # v0 = right
lw $v0,28($fp) # v1 = left
slt $a0,$v0,$v1 # a0 = v1 > v0 ? 0 : 1
beq $a0,$zero,L7
move $v0,$v1 # executed when v1 > v0
L7:
addiu $v0,$v0,1 # executed when v0 < v1
L6:
# epilogue
move $sp,$fp
lw $ra,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
jr $ra
even_level_max:
# prologue
addiu $sp,$sp,-48
sw $ra,44($sp)
sw $fp,40($sp)
move $fp,$sp
sw $a0,48($fp) # fp[48] = root
sw $a1,52($fp) # fp[52] = level
lw $v0,48($fp)
bne $v0,$zero,L9
li $v0, 0x80000000
b L10 # if (root == NULL) return 0x80000000;
L9: # root != NULL
lw $v0,48($fp)
lw $v1,4($v0) # v1 = root -> left
lw $v0,52($fp)
addiu $v0,$v0,1 # v0 = level + 1
move $a1,$v0
move $a0,$v1
jal even_level_max
sw $v0,24($fp) # fp[24] = left = even_level_max(root -> left, level +1)
lw $v0,48($fp)
lw $v1,8($v0) # v1 = root -> right
lw $v0,52($fp)
addiu $v0,$v0,1 # v0 = level + 1
move $a1,$v0
move $a0,$v1
jal even_level_max
sw $v0,28($fp) # fp[28] = right = even_level_max(root -> right, level + 1)
lw $v1,24($fp) # v1 = right
lw $v0,28($fp) # v0 = left
slt $a0,$v0,$v1 # a0 = v1 > v0 ? 0 : 1
beq $a0,$zero,L11
move $v0,$v1
L11:
sw $v0,32($fp) # fp[32] = greater
lw $v0,52($fp) # v0 = level
andi $v0,$v0,0x1 # v0 & 1
bne $v0,$zero,L12
lw $v0,48($fp) # v0 = root
lw $v1,0($v0) # v1 = data
lw $v0,32($fp) # v0 = greater
slt $a0,$v0,$v1 # a0 = v1 > v0 ? 0 : 1
beq $a0,$zero,L10 # return greater
move $v0,$v1 # v0 = data
b L10 # return data
L12:
lw $v0,32($fp) # return greater
L10:
# epilogue
move $sp,$fp
lw $ra,44($sp)
lw $fp,40($sp)
addiu $sp,$sp,48
jr $ra
Related
So I have this code snippet in C
int unit_test_case08(int a, int b)
{
int success = 1336;
if(a != b)
{
success = 1337;
}
else
{
success = -1;
}
return success;
}
Which translates in MIPS to
unit_test_case08:
addiu $sp,$sp,-24
sw $fp,20($sp)
move $fp,$sp
sw $4,24($fp)
sw $5,28($fp)
sw $6,32($fp)
li $2,1336 # 0x538
sw $2,8($fp)
lw $3,24($fp)
lw $2,28($fp)
nop
beq $3,$2,$L2
nop
li $2,1337 # 0x539
sw $2,8($fp)
b $L3
nop
$L2:
li $2,-1 # 0xffffffffffffffff
sw $2,8($fp)
$L3:
lw $2,8($fp)
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
jr $31
nop
But for my question, im trying to create some test cases for my emulator, but am finding it hard to generate some code in C that will get me BEQL instead of BEQ?
beq $3,$2,$L2
This question extends to most of the "Likelys" if possible.
I am a very new to MIPS.
I would like to learn how to code a test case in C that would translate to BEQL instead of BEQ.
I'm trying to implement a merge sort algorithm in MIPS using linked lists. I'm basically trying to translate this code: http://www.geeksforgeeks.org/merge-sort-for-linked-list/
However, I'm having some issues. The sorted list is incomplete as if it had lost an entire recursive branch, for example, this is the linked list to sort:
4 -> 3 -> 1 -> 2
And the output is: 1 -> 2 -> 4. And then comes an error when I try to write the list to a file (Runtime exception at 0x004003fc: address out of range 0x00000000). I'm guessing that's because I expect to print 4 numbers, but I only have 3 numbers in the list.
I think where I need help is in the MergeSort function, as I don't COMPLETELY understand what it actually does pointer-wise. This is what I think it does:
It receives as a parameter a pointer to a pointer to the head of the list. Inside the function, it creates the "head" pointer, and it points to the VALUE of headRef (in this case, &head was passed on main, so now "head" inside the function has the address of head in the main). Then it declares two pointers, a and b (in MIPS this would be like doing a = 0, and b = 0? I can't "declare" registers). Then it checks if the list has 1 or 0 elements and returns if it does. Otherwise, it splits the list into two halves with FrontBackSplit(head, &a, &b), but this is the tricky par... this function doesn't return anything. Instead, it modifies the pointers "a" and "b", to make them point to the first half of the list, and the second half, respectively. In MIPS, I would think this as two return values $v0 and $v1. Then it sorts the list recursively, starting from the left, but once again, it doesn't return anything... it modifies the pointer "a" and "b". Finally, it changes the value of the pointer to the head of the list to make it point to the new sorted list.
Because of so many **ptr and &ptr values, I'm confused on what to save on the stack. This is what I ahve so far, regarding that function:
# void mergesort(node** headRef)
# input $a0: head of the list
mergesort:
move $t0, $s3 # node* head = headRef
li $t1, 0 # node* a
li $t2, 0 # node* b
# if(head == NULL || head->next == NULL)
beqz $t0, mergesort_return
lw $t3, node_next($t0) # $t3 = head->next
beqz $t3, mergesort_return
move $a0, $t0
move $a1, $t1
move $a2, $t2
# save head and $ra
addi $sp, $sp, -8
sw $t0, 0($sp)
sw $ra, 4($sp)
jal frontbacksplit
# restore head and $ra
lw $t0, 0($sp)
lw $ra, 4($sp)
addi $sp, $sp, 8
# save output results
move $t1, $v0 # a now points to the first half + 1 (if odd) of the list (frontRef)
move $t2, $v1 # b now points to the second half of the list (backRef)
# save head, a, b and $ra
addi $sp, $sp, -16
sw $t0, 0($sp)
sw $t1, 4($sp)
sw $t2, 8($sp)
sw $ra, 12($sp)
# mergesort(a)
move $a0, $t1
jal mergesort
# restore registers and $ra
lw $t0, 0($sp)
lw $t1, 4($sp)
lw $t2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
# save head, a, b and $ra
addi $sp, $sp, -16
sw $t0, 0($sp)
sw $t1, 4($sp)
sw $t2, 8($sp)
sw $ra, 12($sp)
# mergesort(b)
move $a0, $t2
jal mergesort
# restore registers and $ra
lw $t0, 0($sp)
lw $t1, 4($sp)
lw $t2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
move $a0, $t1
move $a1, $t2
# save head, a, b and $ra
addi $sp, $sp, -16
sw $t0, 0($sp)
sw $t1, 4($sp)
sw $t2, 8($sp)
sw $ra, 12($sp)
jal sortedmerge
# restore registers and $ra
lw $t0, 0($sp)
lw $t1, 4($sp)
lw $t2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
move $s3, $v0 # s3 is the saved head of the original list declared in main
mergesort_return:
jr $ra
Well... I did it. This was a homework and hasn't been graded. I hope they don't think I copied it lol.
######### uses function frontbacksplit
######### WORKING
# mergesort
# input $a0: head of the list to merge
mergesort:
li $t0, 0 # head_one = NULL
li $t1, 0 # head_two = NULL
# base case
beqz $a0, mergesort_return
lw $t2, node_next($a0)
beqz $t2, mergesort_return
addi $sp, $sp, -8
sw $ra, 0($sp)
sw $a0, 4($sp)
# move $a0, $a0
move $a1, $t0
move $a2, $t1
jal frontbacksplit
move $t0, $v0
move $t1, $v1
lw $ra, 0($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8
# mergesort(a)
addi $sp, $sp, -16
sw $ra, 0($sp)
sw $t0, 4($sp)
sw $t1, 8($sp)
sw $a0, 12($sp)
move $a0, $t0
jal mergesort # mergesort(a)
move $t9, $v0
lw $ra, 0($sp)
lw $t0, 4($sp)
lw $t1, 8($sp)
lw $a0, 12($sp)
addi $sp, $sp, 16
# mergesort(b)
addi $sp, $sp, -20
sw $ra, 0($sp)
sw $t0, 4($sp)
sw $t1, 8($sp)
sw $a0, 12($sp)
sw $t9, 16($sp)
move $a0, $t1
jal mergesort # mergesort(b)
move $t8, $v0
lw $ra, 0($sp)
lw $t0, 4($sp)
lw $t1, 8($sp)
lw $a0, 12($sp)
lw $t9, 16($sp)
addi $sp, $sp, 20
# t8 = a, t9 = b
addi $sp, $sp, -24
sw $ra, 0($sp)
sw $t0, 4($sp)
sw $t1, 8($sp)
sw $a0, 12($sp)
sw $t9, 16($sp)
sw $t8, 20($sp)
move $a0, $t8
move $a1, $t9
jal merge
lw $ra, 0($sp)
lw $t0, 4($sp)
lw $t1, 8($sp)
lw $a0, 12($sp)
lw $t9, 16($sp)
lw $t8, 20($sp)
addi $sp, $sp, 24
#move $v0, $v0
jr $ra
mergesort_return:
move $v0, $a0
jr $ra
######### WORKING
# input $a0: source node (list to split)
# input $a1: front ref (a) $s4
# input $a2: back ref (b) $s5
# output $v0: frontRef
# output $v1: backRef
frontbacksplit:
# $a0 = node* source, $a1 = node* frontRef, $a2 = node* backRef
move $t0, $a0 # $t0 = source
move $t1, $a1 # $t1 = frontRef
move $t2, $a2 # $t2 = backRef
li $t3, 0 # node* fast;
li $t4, 0 # node* slow;
# if(source == NULL)
beqz $t0, frontbacksplit_sorted
lw $t5, node_next($t0) # $t5 = source->next
# if(source->next == NULL)
beqz $t5, frontbacksplit_sorted
# else
move $t4, $t0 # slow = source
lw $t3, node_next($t0) # fast = source->next
frontbacksplit_while:
# while(fast != NULL)
beqz $t3, frontbacksplit_endwhile
lw $t3, node_next($t3) # fast = fast->next
# if(fast != NULL)
beqz $t3, frontbacksplit_while
lw $t4, node_next($t4) # slow = slow->next
lw $t3, node_next($t3) # fast = fast->next
j frontbacksplit_while
frontbacksplit_endwhile:
move $t1, $t0 # frontRef = source
lw $t2, node_next($t4) # backRef = slow->next
sw $zero, node_next($t4) # slow->next = NULL
move $v0, $t1
move $v1, $t2
j frontbacksplit_end
frontbacksplit_sorted:
move $v0, $t0 # frontRef = source
li $v1, 0 # backRef = NULL
frontbacksplit_end:
jr $ra
############ WORKING
# input $a0: head of the first list
# input $a1: head of the second list
# output $v0: pointer to the head of the merged-sorted list
merge:
beqz $a0, merge_return2
beqz $a1, merge_return1
li $t3, 0 # head_three = NULL
lw $t0, node_int($a0)
lw $t1, node_int($a1)
addi $sp, $sp, -16
sw $ra, 0($sp)
sw $a0, 4($sp)
sw $a1, 8($sp)
sw $t3, 12($sp)
bge $t0, $t1, merge_else
# if head_one->num < head_two->num
lw $a0, node_next($a0)
# $a1 already has head_two
jal merge
move $t0, $v0 # ptr = merge(head_one->next, head_two)
# restore values
lw $ra, 0($sp)
lw $a0, 4($sp)
lw $a1, 8($sp)
lw $t3, 12($sp)
move $t3, $a0
sw $t0, node_next($t3)
move $v0, $t3
addi $sp, $sp, 16
jr $ra
merge_else:
# $a0 already has head_one
lw $a1, node_next($a1)
jal merge
move $t0, $v0 # ptr = merge(head_one->next, head_two)
# restore values
lw $ra, 0($sp)
lw $a0, 4($sp)
lw $a1, 8($sp)
lw $t3, 12($sp)
move $t3, $a1
sw $t0, node_next($t3)
move $v0, $t3
addi $sp, $sp, 16
jr $ra
merge_return1:
move $v0, $a0
jr $ra
merge_return2:
move $v0, $a1
jr $ra
I know it's quite messy but it works :P.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I was trying to convert C code to MIPS assembly. Here's a snippet. The problem is that i'm not too sure if i am going along the right track. I'm hoping, someone could help.
This was the original question:
void swap(int v[], int k, int j) {
int temp;
temp = v[k];
v[k] = v[j];
v[j] = temp;
}
and this is how far i have got:
swap:
addi $sp, $sp, -4
sw $s0, 0($sp)
add $s0, $zero, $zero
L1: add $t1, $s0, $a1
lb $t2, 0($t1)
add $t3, $s0, $a0
sb $t2, 0($t3)
beq $t2, $zero, L2
addi $s0, $s0, 1
j L1
L2: lw $s0, 0($sp)
addi $sp, $sp, 4
jr $ra
Alright this is as far as i have got. Am i doing this right or am i completely lost it!?
break it down and then implement it
v, k and j come in as registers we assume.
you need to build the address v+(k<<2) and v+(j<<2) You can use scratch registers, I assume you can trash the k and j incoming registers too since you wont need them anymore.
k = k << 2;
k = k + v
j = j << 2;
j = j + v
temp0 = load(k)
temp1 = load(j)
store(k) = temp1
store(j) = temp0
and you should be able to convert that to asm, can re-arrange some of the instructions and have it still work.
Edit, I will let you figure it out, but I didnt cheat and compile first. But found that gcc produced the same basic sequence of instructions. Two shifts, two adds two loads, then two stores.
Here's a free online tool that converts c code to assembly.
Here is the converted code:
addiu $sp,$sp,-24
$LCFI0:
sw $fp,20($sp)
$LCFI1:
move $fp,$sp
movz $31,$31,$0
$LCFI2:
sw $4,24($fp)
sw $5,28($fp)
sw $6,32($fp)
lw $2,28($fp)
nop
sll $2,$2,2
lw $3,24($fp)
nop
addu $2,$3,$2
lw $2,0($2)
nop
sw $2,8($fp)
lw $2,28($fp)
nop
sll $2,$2,2
lw $3,24($fp)
nop
addu $2,$3,$2
lw $3,32($fp)
nop
sll $3,$3,2
lw $4,24($fp)
nop
addu $3,$4,$3
lw $3,0($3)
nop
sw $3,0($2)
lw $2,32($fp)
nop
sll $2,$2,2
lw $3,24($fp)
nop
addu $2,$3,$2
lw $3,8($fp)
nop
sw $3,0($2)
move $sp,$fp
lw $fp,20($sp)
addiu $sp,$sp,24
j $31
nop
This is code in C language:
while(a<10){
M[a] = a + b;
a++; }
How to rewrite it in assembly language in Mips and don't use pseudo instructions.
M is array of 32bit elements. a in register $s0, b in $s1, $s2 is base address of M array.
And my code it:
addi $s3, $zero, 10
LOOP: add $st1, $s0, $s1
add $t2, $s2, $s0
sw $t1, 0($s2)
addi $s0, $s0, 1
bne $s0, $s3, LOOP
but i think it has problem.
Thank you very much.
If I take this C program and compile it to MIPS assembly:
int main() {
int b = 10;
int a = 20;
int M[20];
while(a<10){
M[a] = a + b;
a++; }
}
Then with my toolchain the MIPS assembly becomes:
.file 1 "Cprogram.c"
# -G value = 8, Cpu = 3000, ISA = 1
# GNU C version cygnus-2.7.2-970404 (mips-mips-ecoff) compiled by GNU C version cygnus-2.7.2-970404.
# options passed: -msoft-float
# options enabled: -fpeephole -ffunction-cse -fkeep-static-consts
# -fpcc-struct-return -fcommon -fverbose-asm -fgnu-linker -msoft-float
# -meb -mcpu=3000
gcc2_compiled.:
__gnu_compiled_c:
.text
.align 2
.globl main
.ent main
main:
.frame $fp,112,$31 # vars= 88, regs= 2/0, args= 16, extra= 0
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,112
sw $31,108($sp)
sw $fp,104($sp)
move $fp,$sp
jal __main
li $2,10 # 0x0000000a
sw $2,16($fp)
li $2,20 # 0x00000014
sw $2,20($fp)
$L2:
lw $2,20($fp)
slt $3,$2,10
bne $3,$0,$L4
j $L3
$L4:
lw $2,20($fp)
move $3,$2
sll $2,$3,2
addu $4,$fp,16
addu $3,$2,$4
addu $2,$3,8
lw $3,20($fp)
lw $4,16($fp)
addu $3,$3,$4
sw $3,0($2)
lw $2,20($fp)
addu $3,$2,1
sw $3,20($fp)
j $L2
$L3:
$L1:
move $sp,$fp # sp not trusted here
lw $31,108($sp)
lw $fp,104($sp)
addu $sp,$sp,112
j $31
.end main
I have code C :
for (i=0; i<98; i++) {
C[i] = A[i+1] - B[i+2] * A[1];
}
first address of array A,B,C are A000h,B000h,C000h
and i transform to mips
addi $a0,$zero,A000h
addi $a1,$zero,B000h
addi $a2,$zero,C000h
li $t0,1
li $t1,98
loop:
addi $a0,0
addi $t2,$a0,4
addi $a1,8
addi $a2,0
lw $t3,0($a0)
lw $t4,4($t2)
lw $t5,8($a1)
mult $t5,$t5,$t3
sub $t6,$t4,$t5
sw $t6,0($a2)
addi $t0,1
bne $t0,$t1,loop
plz check it,thank
You can compile C to MIPS assembly and look at the output if it helps. The following C:
int main ()
{
int i;
int A[99], B[99], C[99];
for (i=0; i<98; i++) {
C[i] = A[i+1] - B[i+2] * A[1];
}
}
compiles with my compiler to this MIPS code
.file 1 "loop.c"
# -G value = 8, Cpu = 3000, ISA = 1
# GNU C version cygnus-2.7.2-970404 (mips-mips-ecoff) compiled by GNU C version cygnus-2.7.2-970404.
# options passed: -msoft-float
# options enabled: -fpeephole -ffunction-cse -fkeep-static-consts
# -fpcc-struct-return -fcommon -fverbose-asm -fgnu-linker -msoft-float
# -meb -mcpu=3000
gcc2_compiled.:
__gnu_compiled_c:
.text
.align 2
.globl main
.ent main
main:
.frame $fp,1232,$31 # vars= 1208, regs= 2/0, args= 16, extra= 0
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,1232
sw $31,1228($sp)
sw $fp,1224($sp)
move $fp,$sp
jal __main
sw $0,16($fp)
$L2:
lw $2,16($fp)
slt $3,$2,98
bne $3,$0,$L5
j $L3
$L5:
lw $2,16($fp)
move $3,$2
sll $2,$3,2
addu $4,$fp,16
addu $3,$2,$4
addu $2,$3,808
addu $3,$fp,28
lw $4,16($fp)
move $5,$4
sll $4,$5,2
addu $3,$3,$4
addu $4,$fp,432
lw $5,16($fp)
move $6,$5
sll $5,$6,2
addu $4,$4,$5
lw $5,0($4)
lw $4,28($fp)
mult $5,$4
lw $3,0($3)
mflo $7
subu $4,$3,$7
sw $4,0($2)
$L4:
lw $2,16($fp)
addu $3,$2,1
sw $3,16($fp)
j $L2
$L3:
$L1:
move $sp,$fp # sp not trusted here
lw $31,1228($sp)
lw $fp,1224($sp)
addu $sp,$sp,1232
j $31
.end main