Arm to mips
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"