Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

Pls need help for this problem need comments and full explanation: Write and test an ARMv8 program to solve the Ackermann function. Please test with

Pls need help for this problem need comments and full explanation:

Write and test an ARMv8 program to solve the Ackermann function.

Please test with small values and check against an online solver. This grows very fast. There is an Ackermann solver on WolframAlpha:

The Ackermann function is the simplest example of a well-defined total function which is computable but not primitive recursive. We use this as a stress test for machines and compilers. You just need to get a working solution for small values.

Consider the following C code that outlines Ackermann function

long long int A (long long int m, long long int n) { if (m == 0) return n+1; else if (n==0) return A(m-1,1); else return A(m-1, A(m, n-1)); }

You need to write a main function that calls the recursive A function and passes arguments m in X0 and n in X1. You may have the function return its result in X0 or X2. This function calls itself recursively (except in the base case) and will be overwriting any registers which are not saved.

You will have a couple of new areas to work on. First, how to implement and call functions. Next, how to properly use the stack.

You will have no idea how deep the recursion will go, so there is no way for you to save values in main memory, as they would be overwritten. In these situations, we store values on the stack to save them. We refer to these as stack frames, and each contains the local variables for a function. This will include the parameters passed in (m and n in this case).

Each time a function is called, it will need to save anything on the stack it wishes to be preserved across function calls. For this program, the only value that you really need to save is m (or m-1). No values are assigned in the function, so it might be tempting to think that no values need to be saved at all, just pass them to the next stage and return what they return. But notice that the third case has a nested recursive call. The call to A(m, n-1) occurs first, and its result will be passed as the second parameter for the outer call. Thus, the value m-1 needs to be passed as the first parameter.

In addition to this parameter, you will also need to save the return address (passed in X30). Recall that the BL (branch and link) opcode transfers control to an address and saves a copy of the program counter (the address of the NEXT instruction after the current one) in X30. When the function completes it should branch to the address in X30 (the RET instruction does this by default). Some of you have noted that X30 will be overwritten if a function calls another function (such as a recursive call). This will keep us from properly returning unless we can save/restore this value.

Any value that must be preserved across a function call (like the two mentioned above) should be placed on the stack. The SP register contains the address of the first free byte on the stack. As values are placed on the stack, the stack pointer is decremented to make room for this value. The stack pointer needs to be incremented or decremented in increments of 16 (to maintain proper alignment of the stack). If you are saving a single value on the stack, you will decrement by 16. If you are saving three values, you will decrement by 32.

When you call a function it should save values on the stack before changing them or calling any other functions. These values should be restored from the stack to their original locations before the function returns.

Here is some pseudo-code for your function:

// X0 contains m // X1 contains n

Function A:

Check if m is zero. If yes, set the return register (X0 or X2) to n+1 and return. Decrement the stack pointer // saving values we need to preserve Save X0 and X30 on the stack. Check if n is zero. If yes, set X0 to m-1 and set X1 to 1. Call A. Else Set X1 to n-1. Call A. // inner call A(m, n-1)

Set X1 to the return value (X0 or X2). Restore X0 from the stack // original m Set X0 to m-1 Call A. // outer call A(m-1, returned-value)

Restore X30 from the stack Return

Input: A(2,2) = 7 (Test on smaller values like A(1,2) first, but submit A(2,2) output)

Submit (Required): a) A file containing your assembly code (.S file) b) A read-me file which indicates your use of registers c) A screenshot of the stack when main calls A d) A screenshot of the stack whenever A(1,0) is called e) A screenshot showing the final register values in main when finished

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image_2

Step: 3

blur-text-image_3

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Database Design Query Formulation And Administration Using Oracle And PostgreSQL

Authors: Michael Mannino

8th Edition

1948426951, 978-1948426954

More Books

Students also viewed these Databases questions