Arm to mips

From EIK wiki

Introduction

In this page there two code example for ARM and MIPS architecture.Main idea is to see the difference between ARM and MIPS. Here only the MIPs assembly is commented. A good read about MIPS Architecture and Assembly Language

MIPS

The MIPS instruction set acknowledges 32 general-purpose registers in the register file. For most processors implementing the MIPS instruction set architecture, each register is 32 bits in size. Registers are designated using the “$” symbol. For all practical purposes, three of these registers have special functionality ($0,29,$31). Also, it should be noted that these registers can be accessed via standardized naming conventions in software. The C/C++ library file “regdef.h” is an implementation of one such naming convention.


Example1 code

int binary(int a, int b)
{
  return a + b;
}

void stk(void)
{
  binary(binary(binary(1, 2), binary(3, 4)), binary(binary(5, 6), binary(7, 8)));
}

Example1 Mips

binary:
        j       $31                     # return
        addu    $2,$4,$5                # r2 = a + b

stk:
        subu    $sp,$sp,32              # allocate space for local vars & 4 slots
        li      $4,0x00000001           # 1
        li      $5,0x00000002           # 2
        sw      $31,24($sp)             # store return address on stack
        sw      $17,20($sp)             # preserve r17 on stack
        jal     binary                  # call binary(1,2)
        sw      $16,16($sp)             # preserve r16 on stack

        li      $4,0x00000003           # 3
        li      $5,0x00000004           # 4
        jal     binary                  # call binary(3,4)
        move    $16,$2                  # r16 = binary(1,2)

        move    $4,$16                  # r4 = binary(1,2)
        jal     binary                  # call binary(binary(1,2), binary(3,4))
        move    $5,$2                   # r5 = binary(3,4)

        li      $4,0x00000005           # 5
        li      $5,0x00000006           # 6
        jal     binary                  # call binary(5,6)
        move    $17,$2                  # r17 = binary(binary(1,2), binary(3,4))

        li      $4,0x00000007           # 7
        li      $5,0x00000008           # 8
        jal     binary                  # call binary(7,8)
        move    $16,$2                  # r16 = binary(5,6)

        move    $4,$16                  # r4 = binary(5,6)
        jal     binary                  # call binary(binary(5,6), binary(7,8))
        move    $5,$2                   # r5 = binary(7,8)

        move    $4,$17                  # r4 = binary(binary(1,2), binary(3,4))
        jal     binary                  # call binary(binary(binary(1,2), binary(3,4)), binary(binary(5,6), binary(7,8)))
        move    $5,$2                   # r5 = binary(binary(5,6), binary(7,8))

        lw      $31,24($sp)             # restore return address from stack
        lw      $17,20($sp)             # restore r17 from stack
        lw      $16,16($sp)             # restore r16 from stack
        addu    $sp,$sp,32              # remove local vars and 4 slots
        j       $31                     # return
        nop


Example1 ARM

binary(int, int):
        push    {r7}
        sub     sp, sp, #12
        add     r7, sp, #0
        str     r0, [r7, #4]
        str     r1, [r7, #0]
        ldr     r2, [r7, #4]
        ldr     r3, [r7, #0]
        adds    r3, r2, r3
        mov     r0, r3
        add     r7, r7, #12
        mov     sp, r7
        pop     {r7}
        bx      lr
stk():
        push    {r4, r5, r7, lr}
        add     r7, sp, #0
        mov     r0, #1
        mov     r1, #2
        bl      binary(int, int)
        mov     r4, r0
        mov     r0, #3
        mov     r1, #4
        bl      binary(int, int)
        mov     r3, r0
        mov     r0, r4
        mov     r1, r3
        bl      binary(int, int)
        mov     r4, r0
        mov     r0, #5
        mov     r1, #6
        bl      binary(int, int)
        mov     r5, r0
        mov     r0, #7
        mov     r1, #8
        bl      binary(int, int)
        mov     r3, r0
        mov     r0, r5
        mov     r1, r3
        bl      binary(int, int)
        mov     r3, r0
        mov     r0, r4
        mov     r1, r3
        bl      binary(int, int)
        pop     {r4, r5, r7, pc}

Example2 code

 int fib(int n) {
 if (n == 0)
   return 0;
 else if (n == 1)
   return 1;
 return fib(n - 1) + fib(n - 2);
  }


Example2 ARM gcc 4.5.3

fib(int):
        push    {r4, r7, lr}
        sub     sp, sp, #12
        add     r7, sp, #0
        str     r0, [r7, #4]
        ldr     r3, [r7, #4]
        cmp     r3, #0
        bne     .L2
        mov     r3, #0
        b       .L3
.L2:
        ldr     r3, [r7, #4]
        cmp     r3, #1
        bne     .L4
        mov     r3, #1
        b       .L3
.L4:
        ldr     r3, [r7, #4]
        add     r3, r3, #-1
        mov     r0, r3
        bl      fib(int)
        mov     r3, r0
        mov     r4, r3
        ldr     r3, [r7, #4]
        sub     r3, r3, #2
        mov     r0, r3
        bl      fib(int)
        mov     r3, r0
        adds    r3, r4, r3
.L3:
        mov     r0, r3
        add     r7, r7, #12
        mov     sp, r7
        pop     {r4, r7, pc}


Example2 MIPs gcc 5.4

$LFB0 = .
fib(int):
        addiu   $sp,$sp,-40
        sw      $31,36($sp)
        sw      $fp,32($sp)
        sw      $16,28($sp)
        move    $fp,$sp
        sw      $4,40($fp)
        lw      $2,40($fp)
        bne     $2,$0,$L2
        nop

        move    $2,$0
        b       $L3
        nop

        lw      $3,40($fp)
        li      $2,1                        # 0x1
        bne     $3,$2,$L4
        nop

        li      $2,1                        # 0x1
        b       $L3
        nop

        lw      $2,40($fp)
        addiu   $2,$2,-1
        move    $4,$2
        jal     fib(int)
        nop

        move    $16,$2
        lw      $2,40($fp)
        addiu   $2,$2,-2
        move    $4,$2
        jal     fib(int)
        nop

        addu    $2,$16,$2
        move    $sp,$fp
        lw      $31,36($sp)
        lw      $fp,32($sp)
        lw      $16,28($sp)
        addiu   $sp,$sp,40
        j       $31
        nop


Example2 MIPs Stack

   
   .text
main:
# Prompt user to input non-negative number
la $a0,prompt   
li $v0,4
syscall

li $v0,5    #Read the number(n)
syscall

move $t2,$v0    # n to $t2

# Call function to get fibonnacci #n
move $a0,$t2
move $v0,$t2
jal fib     #call fib (n)
move $t3,$v0    #result is in $t3

# Output message and n
la $a0,result   #Print F_
li $v0,4
syscall

move $a0,$t2    #Print n
li $v0,1
syscall

la $a0,result2  #Print =
li $v0,4
syscall

move $a0,$t3    #Print the answer
li $v0,1
syscall

la $a0,endl #Print '\n'
li $v0,4
syscall

# End program
li $v0,10
syscall

fib:
# Compute and return fibonacci number
beqz $a0,zero   #if n=0 return 0
beq $a0,1,one   #if n=1 return 1

#Calling fib(n-1)
sub $sp,$sp,4   #storing return address on stack
sw $ra,0($sp)

sub $a0,$a0,1   #n-1
jal fib     #fib(n-1)
add $a0,$a0,1

lw $ra,0($sp)   #restoring return address from stack
add $sp,$sp,4


sub $sp,$sp,4   #Push return value to stack
sw $v0,0($sp)
#Calling fib(n-2)
sub $sp,$sp,4   #storing return address on stack
sw $ra,0($sp)

sub $a0,$a0,2   #n-2
jal fib     #fib(n-2)
add $a0,$a0,2

lw $ra,0($sp)   #restoring return address from stack
add $sp,$sp,4
#---------------
lw $s7,0($sp)   #Pop return value from stack
add $sp,$sp,4

add $v0,$v0,$s7 # f(n - 2)+fib(n-1)
jr $ra # decrement/next in stack

zero:
li $v0,0
jr $ra
one:
li $v0,1
jr $ra

.data
prompt: .asciiz "This program calculates Fibonacci sequence with recursive functions.\nEnter a non-negative number: "
result: .asciiz "F_"
result2: .asciiz " = "
endl: .asciiz "\n"