Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

The interaction between the main program and the function is solely through the

ID: 3891333 • Letter: T

Question

The interaction between the main program and the function is solely through the stack. The function stores $ra immediately after being called and restores $ra before returning to main. The main program reserves a static C like array (index starts from 0) of 10 elements and initializes it. The maximum should be in locations 4 and 5 (same number) and the minimum in location 7. Locations 0, 1, 8, and 9 should contain the same value. Furthermore, the main program stores the base address of the array in $t0 and the array size in $s0 and has to use these registers after calling the function (you do not have to code the register usage). The function receives the starting address of an array of 32-bit integers and the number of elements in the array from the main program, finds the maximum integer, the minimum integer within the array, and the average value of the elements in the array and returns the maximum, minimum, average, and the locations of the minimum and maximum values in the array to the main program. Further assume that the function uses $t0 as a pointer to array elements. Additionally, the function stores the index used to “navigate” through the array in $s0. Hence, both $t0 and $s0 are changed by the function. After calling the function, and receiving the results, the main program prints these results to the screen and stops.

Can you please translate the c++ code below into MIPS assembly language using the instructions above as a guide.

My C++ Code :

#include <iomanip>
#include <iostream>

using namespace std;

void minMaxAvg(int&, int&, double&, int, int&, int&, int *);

int main(){
const int SIZE = 10;

int arr[SIZE] = {2,2,3,4,10,10,5,1,2,2};
int *p;
int max = 0;
int min = arr[0];
int maxPos = 0;
int minPos = 0;

double avg = 0;

p = arr;

minMaxAvg(max, min, avg, SIZE, maxPos, minPos, p);

cout << "Max: " << max << ", Index: " << maxPos << endl;
cout << "Min: " << min << ", Index: " << minPos << endl;
cout << "Average: " << avg << endl;

return 0;
}

void minMaxAvg(int &max, int &min, double &avg, int SIZE, int &maxPos, int &minPos,int *p){
for(int i = 0; i < SIZE; i++){
if(*(p + i) > max){
max = *(p + i);
maxPos = i;
}
}
for(int i = 0; i < SIZE; i++){
if(*(p + i) < min){
min = *(p + i);
minPos = i;
}
}
for(int i = 0; i < SIZE; i++){
avg = avg + *(p + i);
}
avg = avg / SIZE;
}

Explanation / Answer

Dear Sir/Madam,

Please find the below assembly code for your c++ code.

Assembly Code:

.LC1 [complete object constructor] [complete object constructor]:

.string "Max: "

.LC2 [base object constructor] [base object constructor]:

.string ", Index: "

.LC3 [complete object allocating constructor] [complete object allocating constructor]:

.string "Min: "

.LC4:

.string "Average: "

main:

push rbp

mov rbp, rsp

sub rsp, 96

mov DWORD PTR [rbp-4], 10

mov DWORD PTR [rbp-64], 2

mov DWORD PTR [rbp-60], 2

mov DWORD PTR [rbp-56], 3

mov DWORD PTR [rbp-52], 4

mov DWORD PTR [rbp-48], 10

mov DWORD PTR [rbp-44], 10

mov DWORD PTR [rbp-40], 5

mov DWORD PTR [rbp-36], 1

mov DWORD PTR [rbp-32], 2

mov DWORD PTR [rbp-28], 2

mov DWORD PTR [rbp-68], 0

mov eax, DWORD PTR [rbp-64]

mov DWORD PTR [rbp-72], eax

mov DWORD PTR [rbp-76], 0

mov DWORD PTR [rbp-80], 0

pxor xmm0, xmm0

movsd QWORD PTR [rbp-88], xmm0

lea rax, [rbp-64]

mov QWORD PTR [rbp-16], rax

lea rdi, [rbp-80]

lea rcx, [rbp-76]

lea rdx, [rbp-88]

lea rsi, [rbp-72]

lea rax, [rbp-68]

sub rsp, 8

push QWORD PTR [rbp-16]

mov r9, rdi

mov r8, rcx

mov ecx, 10

mov rdi, rax

call minMaxAvg(int&, int&, double&, int, int&, int&, int*)

add rsp, 16

mov esi, OFFSET FLAT:.LC1 [complete object constructor] [complete object constructor]

mov edi, OFFSET FLAT:_ZSt4cout

call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)

mov rdx, rax

mov eax, DWORD PTR [rbp-68]

mov esi, eax

mov rdi, rdx

call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

mov esi, OFFSET FLAT:.LC2 [base object constructor] [base object constructor]

mov rdi, rax

call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)

mov rdx, rax

mov eax, DWORD PTR [rbp-76]

mov esi, eax

mov rdi, rdx

call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

mov esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_

mov rdi, rax

call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))

mov esi, OFFSET FLAT:.LC3 [complete object allocating constructor] [complete object allocating constructor]

mov edi, OFFSET FLAT:_ZSt4cout

call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)

mov rdx, rax

mov eax, DWORD PTR [rbp-72]

mov esi, eax

mov rdi, rdx

call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

mov esi, OFFSET FLAT:.LC2 [base object constructor] [base object constructor]

mov rdi, rax

call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)

mov rdx, rax

mov eax, DWORD PTR [rbp-80]

mov esi, eax

mov rdi, rdx

call std::basic_ostream<char, std::char_traits<char> >::operator<<(int)

mov esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_

mov rdi, rax

call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))

mov esi, OFFSET FLAT:.LC4

mov edi, OFFSET FLAT:_ZSt4cout

call std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)

movsd xmm0, QWORD PTR [rbp-88]

mov rdi, rax

call std::basic_ostream<char, std::char_traits<char> >::operator<<(double)

mov esi, OFFSET FLAT:_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_

mov rdi, rax

call std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))

mov eax, 0

leave

ret

minMaxAvg(int&, int&, double&, int, int&, int&, int*):

push rbp

mov rbp, rsp

mov QWORD PTR [rbp-24], rdi

mov QWORD PTR [rbp-32], rsi

mov QWORD PTR [rbp-40], rdx

mov DWORD PTR [rbp-44], ecx

mov QWORD PTR [rbp-56], r8

mov QWORD PTR [rbp-64], r9

mov DWORD PTR [rbp-4], 0

.L6:

mov eax, DWORD PTR [rbp-4]

cmp eax, DWORD PTR [rbp-44]

jge .L4

mov eax, DWORD PTR [rbp-4]

  cdqe

lea rdx, [0+rax*4]

mov rax, QWORD PTR [rbp+16]

add rax, rdx

mov edx, DWORD PTR [rax]

mov rax, QWORD PTR [rbp-24]

mov eax, DWORD PTR [rax]

cmp edx, eax

jle .L5

mov eax, DWORD PTR [rbp-4]

cdqe

lea rdx, [0+rax*4]

mov rax, QWORD PTR [rbp+16]

add rax, rdx

mov edx, DWORD PTR [rax]

mov rax, QWORD PTR [rbp-24]

mov DWORD PTR [rax], edx

mov rax, QWORD PTR [rbp-56]

mov edx, DWORD PTR [rbp-4]

mov DWORD PTR [rax], edx

.L5:

add DWORD PTR [rbp-4], 1

jmp .L6

.L4:

mov DWORD PTR [rbp-8], 0

.L9:

mov eax, DWORD PTR [rbp-8]

cmp eax, DWORD PTR [rbp-44]

jge .L7

mov eax, DWORD PTR [rbp-8]

cdqe

lea rdx, [0+rax*4]

mov rax, QWORD PTR [rbp+16]

add rax, rdx

mov edx, DWORD PTR [rax]

mov rax, QWORD PTR [rbp-32]

mov eax, DWORD PTR [rax]

cmp edx, eax

jge .L8

mov eax, DWORD PTR [rbp-8]

cdqe

lea rdx, [0+rax*4]

mov rax, QWORD PTR [rbp+16]

add rax, rdx

mov edx, DWORD PTR [rax]

mov rax, QWORD PTR [rbp-32]

mov DWORD PTR [rax], edx

mov rax, QWORD PTR [rbp-64]

mov edx, DWORD PTR [rbp-8]

mov DWORD PTR [rax], edx

.L8:

add DWORD PTR [rbp-8], 1

jmp .L9

.L7:

mov DWORD PTR [rbp-12], 0

.L11:

mov eax, DWORD PTR [rbp-12]

cmp eax, DWORD PTR [rbp-44]

jge .L10

mov rax, QWORD PTR [rbp-40]

movsd xmm1, QWORD PTR [rax]

mov eax, DWORD PTR [rbp-12]

cdqe

lea rdx, [0+rax*4]

mov rax, QWORD PTR [rbp+16]

add rax, rdx

mov eax, DWORD PTR [rax]

cvtsi2sd xmm0, eax

addsd xmm0, xmm1

mov rax, QWORD PTR [rbp-40]

movsd QWORD PTR [rax], xmm0

add DWORD PTR [rbp-12], 1

jmp .L11

.L10:

mov rax, QWORD PTR [rbp-40]

movsd xmm0, QWORD PTR [rax]

cvtsi2sd xmm1, DWORD PTR [rbp-44]

divsd xmm0, xmm1

mov rax, QWORD PTR [rbp-40]

movsd QWORD PTR [rax], xmm0

nop

pop rbp

ret

__static_initialization_and_destruction_0(int, int):

push rbp

mov rbp, rsp

sub rsp, 16

mov DWORD PTR [rbp-4], edi

mov DWORD PTR [rbp-8], esi

cmp DWORD PTR [rbp-4], 1

jne .L14

cmp DWORD PTR [rbp-8], 65535

jne .L14

mov edi, OFFSET FLAT:_ZStL8__ioinit

call std::ios_base::Init::Init() [complete object constructor]

mov edx, OFFSET FLAT:__dso_handle

mov esi, OFFSET FLAT:_ZStL8__ioinit

mov edi, OFFSET FLAT:_ZNSt8ios_base4InitD1Ev

call __cxa_atexit

.L14:

nop

leave

ret

_GLOBAL__sub_I_main:

push rbp

mov rbp, rsp

mov esi, 65535

mov edi, 1

call __static_initialization_and_destruction_0(int, int)

pop rbp

ret

if you have any quireis please ping me at yoganjula.g@hotmail.com

Thank you and all the best :)

With Regards,

Yoganjula Reddy G.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote