Question

Below is a C function and a first attempt at translating it into equivalent ARM subroutine....

Below is a C function and a first attempt at translating it into equivalent ARM subroutine. However, while the ARM code assembles successfully, execution of it reveals that it regularly gets stuck within fact in what is apparently an infinite loop. Explain why and explain how you can repair the ARM code so that it returns correctly while preserving the recursive nature of the original C function.

int fact(int n) {
  if (n == 0) {
    return 1;
  } else {
    return n * fact(n - 1);
  }
}

ARM code that needs to be fixed:

fact    CMP R0, #0      ; if argument n is 0, return 1
        MOVEQ R0, #1
        MOVEQ PC, LR
        MOV R3, R0      ; otherwise save argument n

                         ;into R3
        SUB R0, R0, #1  ; and perform recursive call

                        ;on R3 - 1
        BL fact
        MUL R0, R3, R0  ; multiply returned value by n
        MOV PC, LR      ; and return

0 0
Add a comment Improve this question Transcribed image text
Answer #1

The ARM code provided in here doesn't work as expected as it disregards the concept of Stack which is a crucial element when it comes to a recursive code. I am illustrating it with the flowchart of this factorial code below(The Register names are just for illustration purposes).

Let's look at your code step by step:

fact    CMP R0, #0      ; if argument n is 0, return 1
        MOVEQ R0, #1
        MOVEQ PC, LR
        MOV R3, R0      ; otherwise save argument n into R3
        SUB R0, R0, #1  ; and perform recursive call on R3 - 1

Till this point, your code does what it should as part of recursive iteration. However, comes here the fact that at the end of this iteration, the assembler would need to push the items into the stack and create room for another for next recursive call. Use stack pointer to decrement by 8 bytes or 2 words (that essentially grows the stack by 8 bytes)

ADD SP, SP, #-8 ;

Use the first word to save the R14 register's content(in ARM, we call it LR) and second to save R3.

STR LR, [SP,#4]

STR R3, [SP]

Now, we are good to proceed for next recursive call. So, Branch and link to the method name "fact".

        BL fact

Post this, we will have to load with immediate Offset on R3. Use LDR for the same. Also, we are good to proceed for the multiplication part.

LDR R3, [SP]
        MUL R0, R3, R0  ; multiply returned value by n

Let's do the reverse of what we did in the last-to-last step. This is important because we need to free up space that gets deallocated.

LDR LR, [SP,#4]

ADD SP, SP,#8
     MOV PC, LR      ; and return

Do let me know if any step is not clear enough and I will be glad to rephrase or re-try to assist.

Thanks.

Add a comment
Know the answer?
Add Answer to:
Below is a C function and a first attempt at translating it into equivalent ARM subroutine....
Your Answer:

Post as a guest

Your Name:

What's your source?

Earn Coins

Coins can be redeemed for fabulous gifts.

Not the answer you're looking for? Ask your own homework help question. Our experts will answer your question WITHIN MINUTES for Free.
Similar Homework Help Questions
  • Write an equivalent C function and explain what it computes. 3. (10 marks) The following is...

    Write an equivalent C function and explain what it computes. 3. (10 marks) The following is the assembly language translation of a C function mystery: r3, [r0, #0] r3, #0 L3 ldrb cmp beq r3, #0 mov L4: r3, r3, #1 r2, [ro, r3] r2, #0 L4 add ldrb cmp bne .L3: ro, r3 lr mov bx Annotate each line of the function with commentss to explain what each line does. Write an equivalent C function and explain what it...

  • Write an ARM assembly language subroutine (named nfibo) to calculate and return the n-th Fibonacci number....

    Write an ARM assembly language subroutine (named nfibo) to calculate and return the n-th Fibonacci number. Fibonacci numbers (or a Fibonacci sequence) are a series of numbers with a property that the next number in the series is a sum of previous two numbers. Starting the series from 0, 1 as the first two numbers we have 0, 1, (0 + 1) = 1, (1 + 1) = 2, (1 + 2) = 3, (2 + 3) = 5, (3...

  • Write a function (subroutine) that inputs a data value in register r0 and returns value in...

    Write a function (subroutine) that inputs a data value in register r0 and returns value in r0. The function returns y 5 a 1 bx 1 cx2, where a, b, and c are parameters built into the function (i.e., they are not passed to it). The subroutine also performs clipping. If the output is greater than a value d, it is constrained to d (clipped). The input in r0 is a positive binary value in the range 0 to 0xFF....

  • Section B - ARM Assembly Language (25 marks) An ARM instruction set summary is provided at...

    Section B - ARM Assembly Language (25 marks) An ARM instruction set summary is provided at the end of this paper 1. (5 marks) Consider the following assembly instruction STMFD r13!, (r5-6} Before executing this instruction, registers hold the following values: Register Value Register r9 Value r4 0x00400040 0x00000000 r5 r10 0x11223344 0x00800080 r6 0x55667788 r11 0x10001000 r7 0x99aabbcc r12 0x20002000 r8 exddeeff00 r13 ex40004000 What memory locations are affected after executing the above instruction? In a table, with a...

  • Please convert this C function into ARM ASSEMBLY LANGUAGE CORTEX M (Must be cortex m) #include<...

    Please convert this C function into ARM ASSEMBLY LANGUAGE CORTEX M (Must be cortex m) #include<stdio.h> int ascii(char c) {                 return (int)c; } int computeMagicNumber(char* name) {                 int sum, i; //varibales                 sum = 0; //set sum to 0                 //calculate sum                 int N = sizeof(name)/sizeof(name[0]); //get name size                 for(i=0;i<N;i++)                                 sum = sum + (i+1)*ascii(name[i]);                                 return sum%1001; //return magic number MAIN FUNCTION : extern int computeMagicNumber(char *); int main(void) { char name[255]="Yusuf Ozturk"; int magic; magic=computeMagicNumber(name); printf("\n Magic number is %d\n",magic); return...

  • LC3 stack (factorial) I need help in writing factorial in Lc3 language by using stack.. ; Begin ...

    LC3 stack (factorial) I need help in writing factorial in Lc3 language by using stack.. ; Begin reserved section: do not change ANYTHING in reserved section! .ORIG x3000 BR Main ; Parameter and result Param .FILL x0004 Result .BLKW 1 ; Constants Stack .FILL x4000 One .FILL #1 MinusOne .FILL #-1 ; End reserved section: do not change ANYTHING in reserved section! ;------------------------------------------------------------------------------- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; int Factorial(int N) ; Returns N! (must be a recursive function) ; Factorial ;__________________...

  • Your code must approximate the square root of an integer between 0 and 2^31-1 Using integer...

    Your code must approximate the square root of an integer between 0 and 2^31-1 Using integer maths is sufficient (no floating point or fractions are required); your code will return the truncated (integer portion) of the square root. Your code must be in an assembly language subroutine which is called by a C function for testing. Be sure to use registers according to the ARM calling convention. Base your software on the following pseudocode: Approximate square root with bisection method...

  • C++ Recursion Code a function which displays the first n prime numbers. The prototype is: void...

    C++ Recursion Code a function which displays the first n prime numbers. The prototype is: void prime (int) The number of primes to display is passed as the parameter. The function prime itself is not recursive. However, it should call a separate recursive helper function which determines if a given number is prime #include <iostream> using namespace std; void prime(int ) { } int main() {    prime (21);    return 0; }

  • 2. Consider the function george (int n) computed by the following recursive C++ code. int george ...

    2. Consider the function george (int n) computed by the following recursive C++ code. int george (int n) assert (n >= 0) if (n < 2) return 1; else return 2*george ((n+1)/2)+2*george (n/2)+2 george((n-1)/2)+2*george (n/2-1); (c) Design a memoization algorithm to compute george(n) for any given n. You do not have to write C++ code. This algorithm should be much faster than the dynamic programming algorithm. What is its time complexity? 2. Consider the function george (int n) computed by...

  • I need a program in c++ the same as below code but I want it to...

    I need a program in c++ the same as below code but I want it to prompt the user to enter the number of elements after that I want it to ask the user to enter the array elements #include<algorithm> #include<stdio.h> #include<string.h> #include<iostream> using namespace std; int a[50]={2,5,4,3}; bool x[100]; int N=4;//number of elements    int k=10;//target sum int sum;//current target sum int cmp(const void *a,const void *b) { return *(int *)b-*(int *)a; } void backtrace(int n) { if(sum>k) return...

ADVERTISEMENT
Free Homework Help App
Download From Google Play
Scan Your Homework
to Get Instant Free Answers
Need Online Homework Help?
Ask a Question
Get Answers For Free
Most questions answered within 3 hours.
ADVERTISEMENT
ADVERTISEMENT
ADVERTISEMENT