# Create A Simple Calculator In Assembly Language Using NASM Assembly Language Assignment Solution.

## Instructions

Objective
Write a program to create a simple calculator in assembly language using NASM assembly language.

## Requirements and Specifications

You will be writing an elf64 format NASM based LInux assembly language program. This program should be a basic calculator that works with signed integers, supporting negation, addition, subtraction, multiplication, division, and storing numbers. The calculator has a single “memory” location called the accumulator. The accumulator should be a single 32 bit value in (2’s complement representation) that is initially 0. Your program should:
1. Read a character from the keyboard and preform an associated function based on the character read, as follows:
• ’s’ should then read in a possibly negative number (in base 10) and store it in the accumulator ’n’ should negate the value found in the accumulator
• ’+’ should read in another possibly negative number (in base 10) and add that number to the accumulator’s value.
• ’-’ should read in another possibly negative number (in base 10) and subtract tha number from the accumulator’s value.
• ’*’ should read in another possibly negative number (in base 10) and multiply the accumulator by the value read in.
• ’/’ should read in another possibly negative number (in base 10) and divide the accumulator by the value read in. This division should be integer based, and the remainder can be ignored.
• ’d’ should print the value of the accumulator in base 10. Remember that the accumulator might be negative.
• ’b’ should print the value of the accumulator in base 2 (i.e. as a 32 bit binary number.)
• ’q’ should quit the program
Screenshots of output

Source Code

section .data

buffer: TIMES(10) db 0

accumulator: dd 0

section .text

global _start

_start:

repeat:

mov ebx, 1

mov ecx, buffer

mov edx, 10

int 0x80

cmp al, 's' ; if the user entered s

cmp al, 'n' ; if the user entered n

je negate ; negate number

cmp al, '+' ; if the user entered +

je plus ; add another number

cmp al, '-' ; if the user entered +

je minus ; subtract another number

cmp al, '*' ; if the user entered *

je multiply ; multiply another number

cmp al, '/' ; if the user entered /

je divide ; divide another number

cmp al, 'd' ; if the user entered p

je decimal ; print number in base 10

cmp al, 'b' ; if the user entered b

je binary ; print number in binary

cmp al, 'q' ; if user entered q

je exit ; exit program

jmp repeat ; go back to the start

mov [accumulator], eax ; save number in accumulator

jmp repeat ; go back to start

negate:

neg DWORD[accumulator] ; negate the number

jmp repeat ; go back to start

plus:

jmp repeat ; go back to start

minus:

sub [accumulator], eax ; subtract number from accumulator

jmp repeat ; go back to start

multiply:

mul DWORD[accumulator] ; multiply number with accumulator

mov [accumulator], eax ; save result

jmp repeat ; go back to start

divide:

mov ebx, eax ; copy number to ebx

mov eax, [accumulator] ; load accumulator for division

cdq ; extend sign to edx

div ebx ; divide accumulator over number

mov [accumulator], eax ; save result

jmp repeat ; go back to start

decimal:

call printDecimal ; print in decimal

jmp repeat ; go back to start

binary:

call printBinary ; print in binary

jmp repeat ; go back to start

exit:

mov rax, 1

mov rbx, 0

int 0x80

; Print character in al

printChar:

mov [buffer], al ; move char to buffer for printing it

; print character on screen

mov eax, 4 ; write

mov ebx, 1

mov ecx, buffer ; use buffer

mov edx, 1

int 0x80

ret

; Read character and return it in al

mov ebx, 1

mov ecx, buffer ; use buffer

mov edx, 1

int 0x80

mov al, [buffer] ; get red character in al

ret

; Prints the number in eax in binary

printBinary:

mov r12d, eax ; copy number to r12d

mov r13, 32 ; print 32 bits

L1:

mov al, '0' ; put 0 in al to print it

shl r12d, 1 ; shift to put bit in carry flag

jnc L2 ; if bit was zero, go to next

mov al, '1' ; else, put 1 in al to print it

L2:

call printChar ; print character on screen

dec r13 ; decrement number of bits to print

jne L1 ; repeat while not zero

mov al, 10 ; load newline character

call printChar ; print character on screen

ret

; Read an integer and return it in eax

mov r12d, 1 ; set sign to +1

mov r13d, 0 ; set number to zero

L3:

cmp al, '-' ; if it was a minus sign

jne L5 ; if not, go to process digit

mov r12d, -1 ; set sign to -1

L4:

cmp al, 10 ; if it's enter

je L6 ; end loop

L5:

movzx eax, al ; extend al to 32 bits

sub al, '0' ; convert from ascii to digit

imul r13d, 10 ; multiply old number by 10

jmp L4 ; repeat loop

L6:

mov eax, r12d ; load sign

mul r13d ; multiply number by sign

ret

; Print the integer in eax on the screen

printDecimal:

mov rcx, 0 ; push zero on stack

push rcx

cmp eax, 0 ; test if number is negative

jge L7 ; if positive continue

push rax

mov al, '-' ; else, print a minus sign

call printChar

pop rax

neg eax ; convert to positive

L7:

mov edx, 0 ; clear edx before division

mov ecx, 10 ; divide number by 10

div ecx

add dl, '0' ; convert digit to ascii

push rdx ; save digit on stack

cmp eax, 0 ; see if quotient is zero

jne L7 ; continue while not zero

L8:

pop rax ; pop digit from stack

cmp eax, 0 ; if reached the zero

je L9 ; end loop

call printChar ; print digit

jmp L8 ; repeat to print next digit

L9:

mov al, 10 ; load newline character

call printChar ; print character on screen

ret