+1 (315) 557-6473 

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
Simple calculator in assembly language using Nasm

Source Code

 section .data

buffer: TIMES(10) db 0

accumulator: dd 0

 section .text

 global _start

_start:

repeat:

    ; Read character from keyboard:

 mov eax, 3 ; read

 mov ebx, 1

 mov ecx, buffer

 mov edx, 10

 int 0x80

    mov al, [buffer] ; load read character in al

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

    je read ; read a number

    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

read:

    call readInteger ; read integer

    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:

    call readInteger ; read integer

    add [accumulator], eax ; add number to accumulator

    jmp repeat ; go back to start

minus:

    call readInteger ; read integer

    sub [accumulator], eax ; subtract number from accumulator

    jmp repeat ; go back to start

multiply:

    call readInteger ; read integer

    mul DWORD[accumulator] ; multiply number with accumulator

    mov [accumulator], eax ; save result

    jmp repeat ; go back to start

divide:

    call readInteger ; read integer

    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:

    mov eax,[accumulator] ; load number

    call printDecimal ; print in decimal

    jmp repeat ; go back to start

binary:

    mov eax,[accumulator] ; load number

    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

readChar:

    ; read character

 mov eax, 3 ; read

 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

readInteger:

    mov r12d, 1 ; set sign to +1

    mov r13d, 0 ; set number to zero

L3:

    call readChar ; read character

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

    jne L5 ; if not, go to process digit

    mov r12d, -1 ; set sign to -1

L4:

    call readChar ; read character

    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

    add r13d, eax ; add digit to number

    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