Translating a C statement into MIPS assembly instructions? - c

I have another homework question that, like the last question I asked on this site, wasn't explained well by the teacher nor the textbook. Here's the question:
Translate this C statement into MIPS assembly instructions:
B[8] = A[i-j];
Assume variables f, g, h, i and j and are assigned to registers $s0, $s1, $s2, $s3, and $s4, respectively. Assume the base addresses of the arrays A and B are in registers $s6 and $s7, respectively.
Now, where I'm stuck is adding the two variables and using the result as an offset. So far, I have the following:
sub $t0, $s3, $s4 # add values to get offset amount, store in $t0
sll $t1, $t0,2 # multiply the offset by 4, store in $t1
Now, I don't know if I can use $t1 as an offset to access that array element. It looks like the textbook only uses numbers (e.g. 4($s7)) instead of registers (e.g. $t1($s7)) What do I do next?

A compiler can only translate complete program, so here's a complete program that includes your instruction, with its translating into MIPS asembly instrution. I hope you can study what's being done here and draw some conclusions.
int main() {
int i = 3;
int j = 2;
int B[3] = {10, 20, 30};
int A[3] = {100, 200, 300};
B[8] = A[i-j];
}
MIPS for the above:
.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:
.rdata
.align 2
$LC0:
.word 10
.word 20
.word 30
.align 2
$LC1:
.word 100
.word 200
.word 300
.text
.align 2
.globl main
.ent main
main:
.frame $fp,64,$31 # vars= 40, regs= 2/0, args= 16, extra= 0
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,64
sw $31,60($sp)
sw $fp,56($sp)
move $fp,$sp
jal __main
li $2,3 # 0x00000003
sw $2,16($fp)
li $2,2 # 0x00000002
sw $2,20($fp)
addu $2,$fp,24
la $3,$LC0
lw $4,0($3)
lw $5,4($3)
lw $6,8($3)
sw $4,0($2)
sw $5,4($2)
sw $6,8($2)
addu $2,$fp,40
la $3,$LC1
lw $4,0($3)
lw $5,4($3)
lw $6,8($3)
sw $4,0($2)
sw $5,4($2)
sw $6,8($2)
lw $2,16($fp)
lw $3,20($fp)
subu $2,$2,$3
move $3,$2
sll $2,$3,2
addu $3,$fp,16
addu $2,$2,$3
addu $3,$2,24
lw $2,0($3)
sw $2,56($fp)
$L1:
move $sp,$fp # sp not trusted here
lw $31,60($sp)
lw $fp,56($sp)
addu $sp,$sp,64
j $31
.end main

Related

I can't understand a portion of code from a MIPS problem

So, I have a problem which translates a C program that calculates the sum of n numbers with a function with a variable number of parameters.
#include<stdarg.h>
int sum(int n, ...){
int i,s;
va_list l;
va_start(l,n);
s=0;
for(i=0;i<n;++i) s+=va_arg(l,int);
va_end(l);
return s;
}
int s;
void main(){
s=sum(3,1,2,3);
s=sum(2,10,20);
}
Here is the MIPS code (ignore the comments), but I can't understand the part below bge, specifically the $t0 operations, what exactly happens when it adds 4 to $t0, I know that if it stores an integer it will simply add 4 to that number, and if I refer to the $sp, then add $sp, 4 would mean the pop operation. I'm really confused about what is happening on that part.
.data
s: .space 4
.text
main:
subu $sp,16 # incarcam parametrii, conform conventiei C
li $t0,3
sw $t0,12($sp)
li $t0,2
sw $t0,8($sp)
li $t0,1
sw $t0,4($sp)
li $t0,3
sw $t0,0($sp)
jal sum # functia returneaza in $v0
addu $sp,16 # descarcam atatia par. cati am incarcat (adica 4 parametri)
sw $v0,s # val. ret. este in $v0
# acum s contine 6
subu $sp,12
li $t0,20
sw $t0,8($sp)
li $t0,10
sw $t0,4($sp)
li $t0,2
sw $t0,0($sp)
jal sum
addu $sp,12 # acum am incarcat doar 3 par., deci descarc doar 3 par.
sw $v0,s
# acum s contine 30
li $v0,10
syscall
sum: # primeste o stiva de forma $sp:(n)()()()...
subu $sp,16 # rezerv loc pt. salvat $fp si pentru i,s,l din functie
sw $fp,12($sp)
addiu $fp,$sp,12
# acum stiva este $sp:(l)(s)(i)$fp:($fp v)(n)()()()...
addu $t0,$fp,8
sw $t0,-12($fp) # va_start(l,n); avem $sp:(l)(s)(i)$fp:($fp v)(n)l:()()...
sw $zero,-8($fp) # s=0
sw $zero,-4($fp) # i=0
sum_et1:
lw $t0,-4($fp)
lw $t1,4($fp)
bge $t0,$t1,sum_et2 # daca i>=n iesim
lw $t0,-12($fp)
addu $t0,4 # 4 este sizeof(int)
sw $t0,-12($fp)
lw $t0,-4($t0) # 4 este sizeof(int)
lw $t1,-8($fp)
add $t1,$t1,$t0
sw $t1,-8($fp) # s+=va_arg(i,int)
lw $t0,-4($fp)
add $t0,1
sw $t0,-4($fp) # ++i
b sum_et1
sum_et2:
# in aceasta implementare nu avem ce executa pentru va_end(l)
lw $v0,-8($fp)
lw $fp,0($fp)
addu $sp,16
jr $ra
My MIPS assembly is very rusty, but it would seem:
lw $t0,-12($fp) # load va_list l
addu $t0,4 # increment l to the next int argument
sw $t0,-12($fp) # store l
lw $t0,-4($t0) # load the argument pointed to by l (still in $t0)
lw $t1,-8($fp) # load sum
add $t1,$t1,$t0 # add the argument to sum
sw $t1,-8($fp) # store sum
lw $t0,-4($fp) # load i
add $t0,1 # increment i by 1
sw $t0,-4($fp) # store i
I suppose the confusing part is that va_list l contains a pointer internally, and is incremented inside the va_arg macro.

C to MIPS - Instruction references undefined QTSpim

I was trying to do an assignment translating from C to MIPS but I get a instruction reference error in jal main. Here is what I have to translate:
void swap (int a, int b)
{
int temp=a;
a=b;
b=temp;
}
int distance (int a, int b)
{
if (b > a)
swap (a,b);
return (a-b)
}
And here is what I wrote:
.data #declare the variables
var1: .word 4, 7, 12, 5
var2: .word 15, 3, 6, 14
result: .space 4
.text
main:
la $t0, var1 #load address 'var1' into $t0
la $t1, var2 #load address 'var2' into $t1
la $t2, result #load address 'result' into $t2
li $t3, 0 # load imm (i=0)
for_loop:
bgt $t3, 4, for_done #when i>4 do not meet condition, exit
lw $t4, 0($t4) #result[i] = tmp
jal distance
addi $t3, $t3, 1 #i++
j for_loop
for_done:
la $t2, distance
ori $v0, $0, 4
syscall
distance:
blt $t0, $t1, exit
jal swap
sub $t5, $t0, $t1
jr $t5
swap:
lw $t6, 0($t0)
lw $t7, 0($t1)
sw $t6, 0($t1)
sw $t7, 0($t0)
exit:
I actually don't know what am I doing, just the basics of Assembly. I hope some of you could help me. :)
I'm sorry but your asm code had [at least] 15 bugs.
I've created two versions: one with the bugs annotated and a second with the bugs fixed and a working program
Note that due to the vagueness of the C code, I had to guess the true intent of the program and take [considerable] poetic license.
Here's the unchanged version with the bugs annotated [please pardon the gratuitous style cleanup]:
.data # declare the variables
var1: .word 4, 7, 12, 5
var2: .word 15, 3, 6, 14
# NOTE/BUG: this only reserves 4 bytes instead of the 16 we need to hold all
# four values
result: .space 4
.text
main:
la $t0,var1 # load address 'var1' into $t0
la $t1,var2 # load address 'var2' into $t1
la $t2,result # load address 'result' into $t2
li $t3,0 # load imm (i=0)
for_loop:
# NOTE/BUG: this goes one too far (i.e. we want i>=4)
bgt $t3,4,for_done # when i>4 do not meet condition, exit
# NOTE/BUG: $t4 is never intialized to anything, so this instruction will fault
# (e.g. equivalent to dererencing a null pointer in C)
lw $t4,0($t4) # result[i] = tmp
jal distance
# NOTE/BUG: the index variable 'i' is incremented, but distance does _not_ use
# (i.e.) distance will always use var1[0] and var2[0] on each iteration
addi $t3,$t3,1 # i++
j for_loop
# NOTE/BUG: what do we want to do here? -- print the result vector presumably
# NOTE/BUG: syscall 4 is to print a string -- it would require setting up $a0
# and _not_ $t2 but, even then, using 'distance' is wrong as distance is the
# function name and _not_ a string so we'd get garbage
# NOTE/BUG: we probably wouldn't even get that far because QtSpim would
# probably fault because distance is in the .text segment and not the .data
# segment
for_done:
la $t2,distance
ori $v0,$0,4
syscall
distance:
# NOTE/BUG: this is comparing _addresses_ instead of _values_ (i.e.) this
# compares (&var1[i] > &var2[i]) instead of var1[i] > var2[i])
# NOTE/BUG: this test is _reversed_, because this guarantees negative numbers
blt $t0,$t1,exit
# NOTE/BUG: jal is calling swap as a function, but swap is merely a label here
jal swap
# NOTE/BUG: based on the mips ABI, return values go into $v0
sub $t5,$t0,$t1
# NOTE/BUG: when 'jal distance' is called, the return address goes into $ra
# and to return to the place in main that called us, we want to do 'jr $ra'
# NOTE/BUG: this 'jr' should be at exit:
jr $t5
# NOTE/BUG: this actually swaps var1[i] and var2[i] -- would this be correct to
# modify the original arrays???
swap:
lw $t6,0($t0)
lw $t7,0($t1)
sw $t6,0($t1)
sw $t7,0($t0)
# NOTE/BUG: this is where the 'jr' should go
exit:
Here's the cleaned up and working version. I decided that it should store the distance in the result vector and then show all three vectors:
.data
# NOTE: lw/sw must be four byte aligned so keep these first
var1: .word 4, 7, 12, 5
var2: .word 15, 3, 6, 14
result: .space 16
msg_var1: .asciiz "var1:"
msg_var2: .asciiz "var2:"
msg_result: .asciiz "dist:"
msg_space: .asciiz " "
msg_nl: .asciiz "\n"
.text
main:
la $s0,var1 # load address of 'var1'
la $s1,var2 # load address of 'var2'
la $s2,result # load address of 'result'
li $s3,4 # number of elements in a given vector
li $s4,0 # load imm (i=0)
for_loop:
bge $s4,$s3,for_done # i <= count? if no, fly
jal distance
addi $s4,$s4,1 # i++
j for_loop
for_done:
la $a0,msg_var1
la $a1,var1
jal show
la $a0,msg_var2
la $a1,var2
jal show
la $a0,msg_result
la $a1,result
jal show
# exit program
li $v0,10
syscall
# distance -- calculate distance between two numbers in two vectors
#
# RETURNS:
# stores into 'result' vector
#
# global registers:
# s0 -- pointer to var1
# s1 -- pointer to var2
# s2 -- pointer to result
# s4 -- array index
#
# registers:
# t0 -- address and value of var1[i]
# t1 -- address and value of var2[i]
# t2 -- temp value
# t7 -- byte offset corresponding to index 'i'
distance:
sll $t7,$s4,2 # convert index to byte offset
addu $t0,$s0,$t7 # get &var1[i]
lw $t0,0($t0) # fetch var1[i]
addu $t1,$s1,$t7 # get &var2[i]
lw $t1,0($t1) # fetch var2[i]
bge $t0,$t1,distance_done # swap a/b to get abs val? if no, fly
# swap a/b
move $t2,$t0 # temp = a
move $t0,$t1 # a = b
move $t1,$t2 # b = temp
distance_done:
sub $v0,$t0,$t1 # get distance (i.e.) abs(a-b)
addu $t2,$s2,$t7 # get &result[i]
sw $v0,0($t2) # result[i] = distance
jr $ra # return
# show -- show vector
#
# arguments:
# a0 -- vector name
# a1 -- pointer to vector
#
# registers:
# t3 -- array remaining count
#
# clobbers:
# v0
show:
li $v0,4 # syscall to print string
syscall
move $t3,$s3 # get number of elements in vector
show_loop:
blez $t3,show_done # more to do? if no, fly
li $v0,4
la $a0,msg_space # output a space
syscall
# output vector[i]
li $v0,1 # syscall to output value
lw $a0,0($a1) # get vector value
syscall
addiu $a1,$a1,4 # advance pointer to next array element
addi $t3,$t3,-1 # bump down count
j show_loop
show_done:
# output newline
la $v0,4
la $a0,msg_nl
syscall
jr $ra # return

how to read array in MIPS

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

C Programming to MIPS Assembly (for Loops)

I'm Trying to convert this C code to MIPS assembly and I am unsure if it is correct. Can someone help me? Please
Question : Assume that the values of a, b, i, and j are in registers $s0, $s1, $t0, and $t1, respectively. Also, assume that register $s2 holds the base address of the array D
C Code :
for(i=0; i<a; i++)
for(j=0; j<b; j++)
D[4*j] = i + j;
My Attempt at MIPS ASSEMBLY
add $t0, $t0, $zero # i = 0
add $t1, $t1, $zero # j = 0
L1 : slt $t2, $t0, $s0 # i<a
beq $t2, $zero, EXIT # if $t2 == 0, Exit
add $t1, $zero, $zero # j=0
addi $t0, $t0, 1 # i ++
L2 : slt $t3, $t1, $s1 # j<b
beq $t3, $zero, L1, # if $t3 == 0, goto L1
add $t4, $t0, $t1 # $t4 = i+j
muli $t5, $t1, 4 # $t5 = $t1 * 4
sll $t5, $t5, 2 # $t5 << 2
add $t5, $t5, $s2 # D + $t5
sw $t4, $t5($s2) # store word $t4 in addr $t5(D)
addi $t0, $t1, 1 # j ++
j L2 # goto L2
EXIT :
add $t0, $t0, $zero # i = 0 Nope, that leaves $t0 unmodified, holding whatever garbage it did before. Perhaps you meant to use addi $t0, $zero, 0?
Also, MIPS doesn't have 2-register addressing modes (for integer load/store), only 16-bit-constant ($reg). $t5($s2) isn't legal. You need a separate addu instruction, or better a pointer-increment.
(You should use addu instead of add for pointer math; it's not an error if address calculation crosses from the low half to high half of address space.)
In C, it's undefined behaviour for another thread to be reading an object while you're writing it, so we can optimize away the actual looping of the outer loop. Unless the type of D is _Atomic int *D or volatile int *D, but that isn't specified in the question.
The inner loop writes the same elements every time regardless of the outer loop counter, so we can optimize away the outer loop and only do the final outer iteration, with i = a-1. Unless a <= 0, then we must skip the outer loop body, i.e. do nothing.
Optimizing away all but the last store to every location is called "dead store elimination". The stores in earlier outer-loop iterations are "dead" because they're overwritten with nothing reading their value.
You normally want to put the loop condition at the bottom of the loop, so the loop branch is a bne $t0, $t1, top_of_loop for example. (MIPS has bne as a native hardware instruction; blt is only a pseudo-instruction unless the 2nd register is $zero.) So we want to optimize j<b to j!=b because we know we're counting upward.
Put a conditional branch before the loop to check if it might need to run zero times. e.g. blez $s0, after_loop to skip the inner loop body if b <= 0.
An idiomatic for(i=0 ; i<a ; i++) loop in asm looks like this in C (or some variation on this).
if(a<=0) goto end_of_loop;
int i=0;
do{ ... }while(++i != a);
Or if i isn't used inside the loop, then i=a and do{}while(--i). (i.e. add -1 and use bnez). Although MIPS can branch just as efficiently on i!=a as it can on i!=0, unlike most architectures with a FLAGS register where counting down saves a compare instruction.
D[4*j] means we stride by 16 bytes in a word array. Separately using a multiply by 4 and a shift by 2 is crazy redundant. Just keep a pointer in a separate register an increment it by 16 every iteration, like a C compiler would.
We don't know the type of D, or any of the other variables for that matter. If any of them are narrow unsigned integers, we might need to implement 8 or 16-bit truncation/wrapping.
But your implementation assumes they're all int or unsigned, so let's do that.
I'm assuming a MIPS without branch-delay slots, like MARS simulates by default.
i+j starts out (with j=0) as a-1 on the last outer-loop iteration that sets the final value. It runs up to j=b-1, so the max value is a-1 + b-1.
Simplifying the problem down to the values we need to store, and the locations we need to store them in, before writing any asm, means the asm we do write is a lot simpler and easier to debug.
You could check the validity of most of these transformations by doing them in C source and checking with a unit test in C.
# int a: $s0
# int b: $s1
# int *D: $s2
# Pointer to D[4*j] : $t0
# int i+j : $t1
# int a-1 + b : $t2 loop bound
blez $s0, EXIT # if(a<=0) goto EXIT
blez $s1, EXIT # if(b<=0) goto EXIT
# now we know both a and b loops run at least once so there's work to do
addiu $t1, $s0, -1 # tmp = a-1 // addu because the C source doesn't do this operation, so we must not fault on signed overflow here. Although that's impossible because we already excluded negatives
addu $t2, $t1, $s1 # tmp_end = a-1 + b // one past the max we store
add $t0, $s2, $zero # p = D // to avoid destroying the D pointer? Otherwise increment it.
inner: # do {
sw $t1, ($t0) # tmp = i+j
addiu $t1, $t1, 1 # tmp++;
addiu $t0, $t0, 16 # 4*sizeof(*D) # could go in the branch-delay slot
bne $t1, $t2, inner # }while(tmp != tmp_end)
EXIT:
We could have done the increment first, before the store, and used a-2 and a+b-2 as the initializer for tmp and tmp_end. On some real pipelined/superscalar MIPS CPUs, that might be better to avoid putting the increment right before the bne that reads it. (After moving the pointer-increment into the branch-delay slot). Of course you'd actually unroll to save work, e.g. using sw $t1, 16($t0) and 32($t0) / 48($t0).
Again on a real MIPS with branch delays, you'd move some of the init of $t0..2 to fill the branch delay slots from the early-out blez instructions, because they couldn't be adjacent.
So as you can see, your version was over-complicated to say the least. Nothing in the question said we have to transliterate each C expression to asm separately, and the whole point of C is the "as-if" rule that allows optimizations like this.
This similar C code compiles and translates to MIPS:
#include <stdio.h>
main()
{
int a,b,i,j=5;
int D[50];
for(i=0; i<a; i++)
for(j=0; j<b; j++)
D[4*j] = i + j;
}
Result:
.file 1 "Ccode.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,240,$31 # vars= 216, regs= 2/0, args= 16, extra= 0
.mask 0xc0000000,-4
.fmask 0x00000000,0
subu $sp,$sp,240
sw $31,236($sp)
sw $fp,232($sp)
move $fp,$sp
jal __main
li $2,5 # 0x00000005
sw $2,28($fp)
sw $0,24($fp)
$L2:
lw $2,24($fp)
lw $3,16($fp)
slt $2,$2,$3
bne $2,$0,$L5
j $L3
$L5:
.set noreorder
nop
.set reorder
sw $0,28($fp)
$L6:
lw $2,28($fp)
lw $3,20($fp)
slt $2,$2,$3
bne $2,$0,$L9
j $L4
$L9:
lw $2,28($fp)
move $3,$2
sll $2,$3,4
addu $4,$fp,16
addu $3,$2,$4
addu $2,$3,16
lw $3,24($fp)
lw $4,28($fp)
addu $3,$3,$4
sw $3,0($2)
$L8:
lw $2,28($fp)
addu $3,$2,1
sw $3,28($fp)
j $L6
$L7:
$L4:
lw $2,24($fp)
addu $3,$2,1
sw $3,24($fp)
j $L2
$L3:
$L1:
move $sp,$fp # sp not trusted here
lw $31,236($sp)
lw $fp,232($sp)
addu $sp,$sp,240
j $31
.end main

how to transform array from C to mips

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

Resources