×
Reviews 4.9/5 Order Now

Create A Simple Calculator in Assembly Language Using NASM Assembly Language Assignment Solution

July 05, 2024
Rehana Magnus
Rehana Magnus
🇨🇦 Canada
Assembly Language
Rehana Magnus, PhD in Computer Science from the esteemed Acadia Institute of Technology, Canada. With 6 years of experience, specializes in assembly language programming. Proficient in low-level coding, optimizing performance, and enhancing system functionality.
Key Topics
  • Instructions
  • Requirements and Specifications
Tip of the day
Leverage OCaml's strong type system to catch errors early. Write modular code using functions and pattern matching for better readability and debugging.
News
A new library for Swift that introduces advanced mathematical functions and types, facilitating complex numerical computations in Swift applications.

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:

Read a character from the keyboard and perform 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 that 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

Related Samples

At ProgrammingHomeworkHelp.com, we offer comprehensive support for Assembly Language assignments. Our website features expertly crafted samples to help you grasp complex concepts and improve your coding skills. These samples serve as valuable resources for understanding syntax, structure, and best practices in Assembly Language programming. With our dedicated assistance, students can tackle their assignments confidently and efficiently. Whether you’re struggling with basic tasks or advanced projects, our expert guidance ensures you achieve academic success in Assembly Language.