views:

3244

answers:

5

I am trying to convert some instruction to MIPS code. But have no idea how to do that.. i know c language so i can decode it to C but dont know how to convert it to MIPS.

  1. I need to write a main
  2. create an array of 10 integers
  3. Declare a variable
  4. make a loop to check if it is odd or even
  5. print a string saying "it is odd or it is even creating if else statement
  6. and increment the variable.

I can write C program for these. But what would it be in MIPS?

int main()
{
  int array[10]={1,2,3,4,5,6,7,8,9,10};
  int i=0;
  while(i<10){
    if(i%2==0)
      printf("It is even\n");
    else
      printf("it is odd\n");
    i=i+1;
  }
  return 0;
}
+1  A: 

Have you tried compiling it with gcc on MIPS?

Grandpa
no i have not but this is what i have so far....txt.globl mainmain:array: .word 0:10 #array of 10 integersli $s0,0li $1,10begin: slt $t0,$s0,$s1bne $t0, $zero,whilewhile:
it sounds like he has to manually compile it, if I'm understanding the question properly...
bdonlan
Why would you have to manually compile it when there are fancy machines to do it for you?
Grandpa
Oh OK, he hadn't added the "homework" tag when I answered.
Grandpa
+5  A: 

Use mips_gcc -S test.c ,the generated assemble code is test.s.

Or you can

    mips_gcc -o test -g test.c
    mips_objdump -Sd test > test_2.s

Compared with the first method , the latter has some benifit :

  • the register is in the form of $v0 ,v$1 instead of $0 , $1
  • you can cross refer to the C code

see the comparison:

     #test.s       - use gcc -S 
    .frame  $fp,24,$31              # vars= 8, regs= 1/0, args= 0, gp= 8
    .mask   0x40000000,-8
    .fmask  0x00000000,0
    .set    noreorder
    .set    nomacro

    addiu   $sp,$sp,-24
    sw      $fp,16($sp)
    move    $fp,$sp
    sw      $0,12($fp)
    li      $2,24                   # 0x18
    sw      $2,8($fp)
    li      $2,3                    # 0x3
    sw      $2,12($fp)
    lw      $3,12($fp)
    lw      $2,8($fp)


 #test_2.s   - use objdump -Sd
 4005c0:   27bdffe8    addiu   sp,sp,-24
 4005c4:   afbe0010    sw  s8,16(sp)
 4005c8:   03a0f021    move    s8,sp
 int a = 0;
 4005cc:   afc0000c    sw  zero,12(s8)
 int b = 24;
 4005d0:   24020018    li  v0,24
 4005d4:   afc20008    sw  v0,8(s8)
 a = 3 ;
 4005d8:   24020003    li  v0,3
 4005dc:   afc2000c    sw  v0,12(s8)
a += b; 
4005e0:   8fc3000c    lw  v1,12(s8)
4005e4:   8fc20008    lw  v0,8(s8)
4005e8:   00000000    nop
pierr
This is out of my knowledge.. all i can understand is the load immediate,load word and the registers :(
A: 
> .txt
.globl main
main:
array: .word 0:10 #array of 10 integers

li $s0,0
li $1,10

begin: 
slt $t0,$s0,$s1
bne $t0, $zero,while

while:
please edit your question to add information; don't add an answer down here (because it's not an answer...)
bdonlan
sorry i am not an expert in these.
Everyone makes mistakes :) Just do try to fix them afterward (eg, you could move this into your question, then delete this answer...)
bdonlan
A: 

Here is some stuff to think about.

Calls to printf: Those involve calling the system call write. Depending on what you want to do, you have 2 choices

  • Call printf function
  • Call write system call via syscall instruction.

compiler generated code and @pierr shows will call printf.

IF you want to work in mips in a "more real than spim or mars" environment, I recommend gxemul. You can simulate a netbsd running on mips.

Inside there, you have gcc, gdb, the works.

So, getting the assembly code of your main function (i.e not objdump) is really easy.

$gcc -S -mrnames main.c

The rest, is quite simple. As you are not asking for a mips to C translation, i'm not going to write the mips code, but will give you some tips.

int i=0;

Ok, this is a WORD, with the value 0x0. In mips, you have a special register ($0) called $zero,which is hardcoded to the 0 value. So to load a variable with 0x0, you have to alternatives.

mv $t1,$zero

or

li $t1,0

(there are more, such as subu $t1,t1,t1, but that's reinventing the wheel)

Then, you have your while loop.

Check your i variable ($t1). You'll have to use a branch instruction for that. Just load the 10 value in another register, and jump to a label according to the result.

Now, loading the array element. THis is the tricky part. That array is NOT in mains stack. Its defined like this.

.rdata
.align 2
$array: .word 1
        .word 2
        .word 3
        //you get the picture right?
main: //main function starts here.

The address of the first element of the array is $array (great isnt it?).

So to load the first (or the nth for that matter) element, just

   la $t3,$array #this load the address of the array into $t3 register
   lw $t2,0($t3) #this does $t2= *(array+0)

So now $t2 contains your array element.

The mod part is REALLY easy. As you are "modding" against 2, you can just take the lsb from your array element, something like

andi $t2,$t2,0x1

Now $t2 contains 1 if the number is odd (lsb is 1) or 0 if its even (lsb is 0). To compare, again, a branch instruction.

When you are done, increment your i variable (use one of the add instructions on t1) and branch back to the comparison.

The return is easy. Return values usually goes in $v0 register (this depends though)

 li $v0,0
 jr $ra
Tom
i can only add and subtract in assembly language(sounds funny right).I am not at all interested in assembly language or even c++ as i am more into networking.This is a mandatory class thus i cannot skip.If you can give me the mips code would be great
I threw in some pointers. You are into networking ? Many routers (linksys i believe) can actually run mips assembly :). I believe it is a good assembly to learn, since its quite simple. And you should do your homework :)
Tom
maan, i am not building routers lol. Right now i do network management for nyinns.com. Kind of internship type.I am getting the picture of it though but all scrambled..not sure how to arrange everything in order..let me see
A: 

try the C/C++ to MIPS Assembly converter at http://ctomips.com. Let me know what you think!

Mark