MIPS Assembly asm Write a recursive MARS program that can co
MIPS Assembly (.asm)
Write a recursive MARS program that can compute the value of an expression in parentheses. The program should accept an input string, sequentially examine each character, invoke the procedure calc_expr every time it sees a new open parenthesis, return from that procedure when the parenthesis is closed, and print the answer when the outermost parenthesis is closed. We will only test with valid inputs including decimal integers, spaces, and +, -, *, / operators. The program runs until the user enters a string starting with \"e\". Within parentheses, the expression is evaluated from left to right, i.e., (6/2+7/5) does 6/2 (which is 3), 3+7 (which is 10), 10/5 (which is 2). Here\'s an example run of the program:
Enter the expression you want evaluated:
((4+3)-((27/9)*2))
The answer is: 1
Enter the expression you want evaluated:
(1*(2 * (3 * (4 * 5))))
The answer is: 120
Enter the expression you want evaluated:
exit
Goodbye
Solution
p:
top:
.zero 8
save:
.zero 8
ptr:
.zero 8
push(int):
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], edi
mov edi, 16
call operator new(unsigned long)
mov QWORD PTR p[rip], rax
mov rax, QWORD PTR p[rip]
mov edx, DWORD PTR [rbp-4]
mov DWORD PTR [rax], edx
mov rax, QWORD PTR p[rip]
mov QWORD PTR [rax+8], 0
mov rax, QWORD PTR top[rip]
test rax, rax
jne .L2
mov rax, QWORD PTR p[rip]
mov QWORD PTR top[rip], rax
jmp .L4
.L2:
mov rax, QWORD PTR top[rip]
mov QWORD PTR save[rip], rax
mov rax, QWORD PTR p[rip]
mov QWORD PTR top[rip], rax
mov rax, QWORD PTR p[rip]
mov rdx, QWORD PTR save[rip]
mov QWORD PTR [rax+8], rdx
.L4:
nop
leave
ret
.LC0:
.string \"underflow!!\"
pop():
push rbp
mov rbp, rsp
mov rax, QWORD PTR top[rip]
test rax, rax
jne .L6
mov esi, OFFSET FLAT:.LC0
mov edi, OFFSET FLAT:std::cout
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*)
jmp .L5
.L6:
mov rax, QWORD PTR top[rip]
mov QWORD PTR ptr[rip], rax
mov rax, QWORD PTR top[rip]
mov rax, QWORD PTR [rax+8]
mov QWORD PTR top[rip], rax
mov rax, QWORD PTR ptr[rip]
mov eax, DWORD PTR [rax]
.L5:
pop rbp
ret
.LC1:
.string \"enter the balanced expression\ \"
.LC2:
.string \"ans is \"
main:
push rbp
mov rbp, rsp
push rbx
sub rsp, 56
mov esi, OFFSET FLAT:.LC1
mov edi, OFFSET FLAT:std::cout
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*)
lea rax, [rbp-64]
mov rsi, rax
mov edi, OFFSET FLAT:std::cin
call std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char*)
mov DWORD PTR [rbp-20], 0
.L19:
mov eax, DWORD PTR [rbp-20]
movsx rbx, eax
lea rax, [rbp-64]
mov rdi, rax
call strlen
cmp rbx, rax
jnb .L10
mov eax, DWORD PTR [rbp-20]
cdqe
movzx eax, BYTE PTR [rbp-64+rax]
cmp al, 47
jle .L11
mov eax, DWORD PTR [rbp-20]
cdqe
movzx eax, BYTE PTR [rbp-64+rax]
cmp al, 57
jg .L11
mov eax, DWORD PTR [rbp-20]
cdqe
movzx eax, BYTE PTR [rbp-64+rax]
movsx eax, al
sub eax, 48
mov edi, eax
call push(int)
jmp .L12
.L11:
mov eax, DWORD PTR [rbp-20]
cdqe
movzx eax, BYTE PTR [rbp-64+rax]
cmp al, 41
jle .L12
mov eax, DWORD PTR [rbp-20]
cdqe
movzx eax, BYTE PTR [rbp-64+rax]
cmp al, 47
jg .L12
call pop()
movsx eax, al
mov DWORD PTR [rbp-24], eax
call pop()
movsx eax, al
mov DWORD PTR [rbp-28], eax
mov eax, DWORD PTR [rbp-20]
cdqe
movzx eax, BYTE PTR [rbp-64+rax]
movsx eax, al
cmp eax, 43
je .L14
cmp eax, 43
jg .L15
cmp eax, 42
je .L16
jmp .L12
.L15:
cmp eax, 45
je .L17
cmp eax, 47
je .L18
jmp .L12
.L14:
mov edx, DWORD PTR [rbp-24]
mov eax, DWORD PTR [rbp-28]
add eax, edx
mov edi, eax
call push(int)
jmp .L12
.L17:
mov eax, DWORD PTR [rbp-24]
sub eax, DWORD PTR [rbp-28]
mov edi, eax
call push(int)
jmp .L12
.L16:
mov eax, DWORD PTR [rbp-24]
imul eax, DWORD PTR [rbp-28]
mov edi, eax
call push(int)
jmp .L12
.L18:
mov eax, DWORD PTR [rbp-24]
cdq
idiv DWORD PTR [rbp-28]
mov edi, eax
call push(int)
nop
.L12:
add DWORD PTR [rbp-20], 1
jmp .L19
.L10:
call pop()
movsx ebx, al
mov esi, OFFSET FLAT:.LC2
mov edi, OFFSET FLAT:std::cout
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 esi, ebx
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)
mov esi, OFFSET FLAT:std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)
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
add rsp, 56
pop rbx
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 .L23
cmp DWORD PTR [rbp-8], 65535
jne .L23
mov edi, OFFSET FLAT:std::__ioinit
call std::ios_base::Init::Init()
mov edx, OFFSET FLAT:__dso_handle
mov esi, OFFSET FLAT:std::__ioinit
mov edi, OFFSET FLAT:std::ios_base::Init::~Init()
call __cxa_atexit
.L23:
nop
leave
ret
_GLOBAL__sub_I_p:
push rbp
mov rbp, rsp
mov esi, 65535
mov edi, 1
call __static_initialization_and_destruction_0(int, int)
pop rbp
ret






