; Subject Code : TMF1214 (Computer Architecture) G11/SE
; Project Title : Programmer Calculator for Conversion of number base and Boolean operation
; Group : 3
; Lecturer Name : DR NORALIFAH ANNUAR
; Group Member : 1) NUR LIYANA BINTI MOHAMED SHAFAWI 85143, 2) NUR NASUHA BINTI NORMAN 82839, 3) MUHAMMAD HAZIM BIN ROHANI 84701, 4) MIRZA MUHAMMAD BIN MUNSHEE 82669, 5) ROBBIE SAMIR ANAK BRUNO 85556, 6) ABG LUQMAN BIN AGB MOHD TAHIR 82335

section .data
    ; Main menu
    msg_menu db 'WELCOME TO PROGRAMMER CALCULATOR', 0xA, 
             db '--------------------------------', 0xA,
             db '||| NUMBER CONVERTER |||', 0xD
             db '1. Decimal to Binary', 0xA, 
             db '2. Decimal to Hexadecimal', 0xA, 
             db '3. Binary to Decimal', 0xA, 
             db '4. Binary to Hexadecimal', 0xA, 
             db '5. Hexadecimal to Decimal', 0xA, 
             db '6. Hexadecimal to Binary', 0xA, 
             db '||| BOOLEAN OPERATIONS |||', 0xD
             db '7. AND', 0xD
             db '8. OR', 0xD
             db '9. XOR', 0xD
             db '10. NOT', 0xD
             db '11. Exit', 0xD
             db 'Enter your choice : ', 

    ; Prompt the user
    msg_decimal db 'Enter a decimal number: ', 0
    msg_binary db 'Enter a binary number: ', 0
    msg_hexadecimal db 'Enter a hexadecimal number: ', 0
    ; Show result
    msg_binary_equivalent db 'Binary equivalent: ', 0
    msg_hexadecimal_equivalent db 'Hexadecimal equivalent: ', 0
    msg_decimal_equivalent db 'Decimal equivalent: ', 0
    msg_invalid_option db 'Invalid option. Please try again.', 0xA, 0xD
    hex_digits db '0123456789ABCDEF'
    newline db 10, 0
    
    AND_prompt:
        db ' ',
    OR_prompt:
        db ' ',    
    XOR_prompt:
        db ' ',    
    NOT_prompt:
        db ' ',  
        
     ; task 2 
     bin1_prompt:
        db 'Enter the first 16-bit binary number: ', 0
    
     bin2_prompt:
        db 'Enter the second 16-bit binary number: ', 0
       
     double_newline:
          db 0xA, 0xA
    
section .bss
    option_input resb 2
    
    ; For conversion from decimal
    num resb 6
    binary resb 16
    hexadecimal resb 4
    ; For conversion from binary
    decimal2 resd 1
    binary2 resb 16
    hexadecimal2 resb 4
    ; For conversion from hexadecimal
    binary3 resb 16
    hexadecimal3 resb 4
    decimal3 resd 1
   
    ;task 2
    bin_number1 resb 17
    bin_number2 resb 17
    result resb 6

section .text
    global _start

_start:
    ; Display menu
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_menu
    mov edx, 318
    int 0x80

    ; Print two newlines
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80         ; call kernel   0020

menu_input:
    ; Read user's option
    mov eax, 3
    mov ebx, 0
    mov ecx, option_input
    mov edx, 3
    int 0x80

    ; Convert the option to an integer
    mov al, [option_input]
    sub al, '0'
    movzx eax, al

    ; Execute the selected option
    cmp eax, 1
    je decimal_to_binary
    cmp eax, 2
    je decimal_to_hexadecimal
    cmp eax, 3
    je binary_to_decimal
    cmp eax, 4
    je binary_to_hexadecimal
    cmp eax, 5
    je hexadecimal_to_decimal
    cmp eax, 6
    je hexadecimal_to_binary
    cmp eax, 7
    je AND_operation
    cmp eax, 8
    je OR_operation
    cmp eax, 9
    je XOR_operation
    cmp eax, 10
    je NOT_operation
    cmp eax, 11
    je exit_program
    
    ; Invalid option
    jmp invalid_option
    
check_input:        ; Incomplete
    ; Check if end of string is reached
    cmp byte [ecx], 0
    je option_input

    ; Check if character is a valid binary digit
    cmp byte [ecx], '0'
    jb invalid_option
    cmp byte [ecx], '1'
    ja invalid_option

    ; Move to the next character
    inc ecx
    loop check_input

; For option 1, convert Decimal to Binary
decimal_to_binary:
    ; Print prompt for decimal input
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_decimal
    mov edx, 24
    int 0x80

read_user_input: 
    ; Read decimal number
    mov eax, 3
    mov ebx, 0
    mov ecx, num
    mov edx, 5
    int 0x80
 
    ; Convert ASCII string to an integer
    xor eax, eax
    xor ebx, ebx

convert_to_integer:
    movzx ecx, byte [num + ebx]
    cmp ecx, '0'
    jb end_convert_to_integer
    cmp ecx, '9'
    ja end_convert_to_integer
    sub ecx, '0'
    imul eax, 10
    add eax, ecx
    inc ebx
    jmp convert_to_integer
    
end_convert_to_integer:
    ; Convert the number to binary
    mov ecx, 16
    mov ebx, eax
    
convert_to_binary:
    xor edx, edx
    mov ecx, 16
    mov ebx, eax
    
convert_decimal_to_binary:
    xor edx, edx
    mov edi, 2
    div edi
    add dl, '0'
    dec ecx
    mov [binary + ecx], dl
    test eax, eax
    jnz convert_decimal_to_binary

    ; If output is not 16 bits yet, pad with zeros
pad_with_zero:
    dec ecx
    cmp ecx, -1
    jz print_binary_result
    mov byte [binary + ecx], '0'
    jmp pad_with_zero

print_binary_result:
    ; Display binary equivalent
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_binary_equivalent
    mov edx, 19
    int 0x80

    ; Print the binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, binary
    mov edx, 16
    int 0x80
    
    ; Print a new line
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    jmp _start
 
; For option 2, convert Decimal to Hexadecimal
decimal_to_hexadecimal:
    ; Display prompt for decimal input
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_decimal
    mov edx, 24
    int 0x80
    
    ; Read decimal number
    mov eax, 3
    mov ebx, 0
    mov ecx, num
    mov edx, 5
    int 0x80

    ; Convert ASCII string to an integer
    xor eax, eax
    xor ebx, ebx

convert_to_integer2:
    movzx ecx, byte [num + ebx]
    cmp ecx, '0'
    jb end_convert_to_integer2
    cmp ecx, '9'
    ja end_convert_to_integer2
    sub ecx, '0'
    imul eax, 10
    add eax, ecx
    inc ebx
    jmp convert_to_integer2
    
end_convert_to_integer2:
    ; Convert the integer to hexadecimal
    mov ecx, 4
    mov ebx, eax
    
convert_to_hexadecimal2:
    xor edx, edx
    mov edi, 16
    div edi
    movzx ebx, dl
    mov dl, byte [hex_digits + ebx]
    dec ecx
    mov [hexadecimal + ecx], dl
    test eax, eax
    jnz convert_to_hexadecimal2

    ; Display hexadecimal equivalent
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_hexadecimal_equivalent
    mov edx, 23 
    int 0x80

    ; Print the hexadecimal number
    mov eax, 4
    mov ebx, 1
    mov ecx, hexadecimal
    mov edx, 4
    int 0x80
    
    ; Print a new line
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    jmp _start

; For option 3, convert Binary to Decimal
binary_to_decimal:
    ; Print prompt for binary input
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_binary
    mov edx, 22
    int 0x80

read_user_binary:
    ; Read binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, binary2
    mov edx, 17 
    int 0x80
    ; Convert binary to decimal
    xor eax, eax
    xor ebx, ebx

convert_binary_to_integer:
    movzx ecx, byte [binary2 + ebx]
    cmp ecx, '0'
    jb end_convert_binary_to_integer
    cmp ecx, '1'
    ja end_convert_binary_to_integer
    sub ecx, '0'
    shl eax, 1
    add eax, ecx
    inc ebx
    cmp ebx, 16
    jb convert_binary_to_integer

end_convert_binary_to_integer:
    ; Store the number in decimal
    mov [decimal2], eax
    ; Display decimal equivalent
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_decimal_equivalent
    mov edx, 19
    int 0x80
    
    ; Print the decimal number
    mov eax, [decimal2]
    call display_decimal_result
    
    jmp _start

display_decimal_result:
    ; Prepare the pointer to the end of buffer
    lea ecx, [num + 4]
    ; Store the number in a buffer
    xor ebx, ebx
    
display_decimal_loop:
    xor edx, edx
    mov edi, 10
    div edi
    add dl, '0'
    dec ecx
    mov [ecx], dl
    inc ebx
    test eax, eax
    jnz display_decimal_loop

    ; Calculate the length
    lea edx, [num + 4]
    sub edx, ecx

    ; Print the decimal number
    mov eax, 4
    mov ebx, 1
    int 0x80
    
    ; Print a new line
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80
    
    jmp _start
 
; For option 4, convert Binary to Hexadecimal   
binary_to_hexadecimal: 
    ; Print prompt for binary input
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_binary
    mov edx, 22
    int 0x80
    ; Read binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, binary2
    mov edx, 17 ; Increase buffer size to accommodate null terminator
    int 0x80
    ; Convert binary to decimal
    xor eax, eax
    xor ebx, ebx
    
convert_binary_to_integer2:
    movzx ecx, byte [binary2 + ebx]
    cmp ecx, '0'
    jb end_convert_binary_to_integer2
    cmp ecx, '1'
    ja end_convert_binary_to_integer2
    sub ecx, '0'
    shl eax, 1
    add eax, ecx
    inc ebx
    cmp ebx, 16
    jb convert_binary_to_integer2

end_convert_binary_to_integer2:
    ; Store the number in decimal
    mov [decimal2], eax

display_decimal2:
    ; Prepare the pointer to the end of buffer
    lea ecx, [num + 4]
    ; Store the number in a buffer
    xor ebx, ebx
    
display_decimal_loop2:
    xor edx, edx
    mov edi, 10
    div edi
    add dl, '0'
    dec ecx
    mov [ecx], dl
    inc ebx
    test eax, eax
    jnz display_decimal_loop2

    ; Convert decimal to hexadecimal
    mov eax, [decimal2]
    mov ecx, 4
    
convert_decimal_to_hexadecimal:
    xor edx, edx
    mov edi, 16
    div edi
    movzx ebx, dl
    mov dl, byte [hex_digits + ebx]
    dec ecx
    mov [hexadecimal2 + ecx], dl
    test eax, eax
    jnz convert_decimal_to_hexadecimal
  
display_hexadecimal_result: 
    ; Print hexadecimal equivalent
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_hexadecimal_equivalent
    mov edx, 23 ; Update to match the actual length of the hexadecimal     equivalent
    int 0x80

    ; Print the hexadecimal number
    mov eax, 4
    mov ebx, 1
    mov ecx, hexadecimal2
    mov edx, 4
    int 0x80
    
    ; Print a new line
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80

    jmp _start
    
; For option 5, convert Hexadecimal to Decimal
hexadecimal_to_decimal:
    ; Print the prompt
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_hexadecimal
    mov edx, 28
    int 0x80

    mov eax, 3
    mov ebx, 0
    mov ecx, hexadecimal3
    mov edx, 5
    int 0x80
    cmp byte [hexadecimal3],10

    ; Convert hexadecimal to decimal
    xor eax, eax
    xor ebx, ebx
    
convert_hexadecimal_to_integer3:
    movzx ecx, byte [hexadecimal3 + ebx]
    cmp ecx, '0'
    jb end_convert_hexadecimal_to_integer3
    cmp ecx, 'F'
    ja end_convert_hexadecimal_to_integer3
    cmp ecx, '9'
    jbe skip_alpha
    sub ecx, 7
    
skip_alpha:
    sub ecx, '0'
    shl eax, 4
    add eax, ecx
    inc ebx
    cmp ebx, 4
    jb convert_hexadecimal_to_integer3
    
end_convert_hexadecimal_to_integer3:
    ; Store the number in decimal
    mov [decimal3], eax

    ; Display decimal equivalent
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_decimal_equivalent
    mov edx, 19
    int 0x80

    ; Display the decimal number
    mov eax, [decimal3]
    
display_decimal3:
    ; Prepare the pointer to the end of buffer
    lea ecx, [num + 4]

    ; Store the number in a buffer
    xor ebx, ebx
    
display_decimal_loop3:
    xor edx, edx
    mov edi, 10
    div edi
    add dl, '0'
    dec ecx
    mov [ecx], dl
    inc ebx
    test eax, eax
    jnz display_decimal_loop3

    ; Calculate the length
    lea edx, [num + 4]
    sub edx, ecx

    ; Display the decimal number
    mov eax, 4
    mov ebx, 1
    int 0x80
    
    ; Print new line
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80
    jmp _start
    
; For option 6, convert Hexadecimal to Binary
hexadecimal_to_binary:
    ; Print the prompt message
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_hexadecimal
    mov edx, 28
    int 0x80

read_hexadecimal:
    ; Read the user's input
    mov eax, 3
    mov ebx, 0
    mov ecx, hexadecimal3
    mov edx, 5
    int 0x80
    
    ; Convert hexadecimal to decimal
    xor eax, eax
    xor ebx, ebx
    
convert_hexadecimal_to_integer1:
    movzx ecx, byte [hexadecimal3 + ebx]
    cmp ecx, '0'
    jb end_convert_hexadecimal_to_integer1
    cmp ecx, 'F'
    ja end_convert_hexadecimal_to_integer1
    cmp ecx, '9'
    jbe skip_alpha1
    sub ecx, 7
    
skip_alpha1:
    sub ecx, '0'
    shl eax, 4
    add eax, ecx
    inc ebx
    cmp ebx, 4
    jb convert_hexadecimal_to_integer1
    
end_convert_hexadecimal_to_integer1:
    ; Store the number in decimal
    mov [decimal3], eax
    ; Prepare the pointer to the end of buffer
    lea ecx, [num + 4]
    ; Store the number in a buffer
    xor ebx, ebx
    ; Calculate the length
    lea edx, [num + 4]
    sub edx, ecx
   ; Convert the number to binary
    mov eax, [decimal3] ; Value of decimal is loaded into eax
    
convert_to_binary2:
    xor edx, edx
    mov ecx, 16
    mov ebx, eax
    
convert_decimal_to_binary2:
    xor edx, edx
    mov edi, 2
    div edi
    add dl, '0'
    dec ecx
    mov [binary3 + ecx], dl
    test eax, eax
    jnz convert_decimal_to_binary2
    
    ; If output is not 16 bits yet, then pad with zeros
pad_with_zero3:
    dec ecx
    cmp ecx, -1
    jle padded
    ; Jump to 'padded' when ecx is less or equal to -1
    mov byte [binary3 + ecx], '0'
    jmp pad_with_zero3
    
padded:
    ; Display binary equivalent
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_binary_equivalent
    mov edx, 18
    int 0x80
    
    mov eax, 4
    mov ebx, 1
    mov ecx, binary3
    mov edx, 16
    int 0x80

    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80
    
    jmp _start
    
invalid_option:
    ; Print error message for invalid option
    mov eax, 4
    mov ebx, 1
    mov ecx, msg_invalid_option
    mov edx, 33
    int 0x80
    
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, 1
    int 0x80
    
    jmp _start
    
exit_program:
    ; Exit the program
    mov eax, 1
    xor ebx, ebx
    int 0x80
    
; Task2
AND_operation:
    ; Prompt for first binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin1_prompt
    mov edx, 38
    int 0x80

    ; Read first binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number1
    mov edx, 17
    int 0x80

    ; Prompt for second binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin2_prompt
    mov edx, 39
    int 0x80

    ; Read second binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number2
    mov edx, 17
    int 0x80

    ; Perform the logical AND operation
    mov eax, 0
    mov ecx, 4
    xor ebx, ebx
    xor edx, edx
    and_loop:
        mov al, byte [bin_number1 + ecx - 1]
        and al, byte [bin_number2 + ecx - 1]
        mov byte [result + ecx - 1], al
        dec ecx
        jnz and_loop
        
    ; Display result
    mov eax, 4
    mov ebx, 1
    mov ecx, result 
    mov edx, 4
    int 0x80
    
    ; Print two newlines
    mov eax, 4
    mov ebx, 1
    mov ecx, double_newline
    mov edx, 2
    int 0x80

    jmp _start


OR_operation:
    ; Prompt for first binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin1_prompt
    mov edx, 38
    int 0x80

    ; Read first binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number1
    mov edx, 17
    int 0x80

    ; Prompt for second binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin2_prompt
    mov edx, 39
    int 0x80

    ; Read second binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number2
    mov edx, 17
    int 0x80
    
    ; Perform the logical OR operation
    mov eax, 0
    mov ecx, 4
    xor ebx, ebx
    xor edx, edx
    or_loop:
        mov al, byte [bin_number1 + ecx - 1]
        or al, byte [bin_number2 + ecx - 1]
        mov byte [result + ecx - 1], al
        dec ecx
        jnz or_loop
        
    ; Display result
    mov eax, 4
    mov ebx, 1
    mov ecx, result 
    mov edx, 4
    int 0x80
    
    ; Print two newlines
    mov eax, 4
    mov ebx, 1
    mov ecx, double_newline
    mov edx, 2
    int 0x80
        
    jmp _start    

XOR_operation:
    ; Prompt for the first binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin1_prompt
    mov edx, 38
    int 0x80

    ; Read the first binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number1
    mov edx, 17
    int 0x80
    
    ; Prompt for second binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin2_prompt
    mov edx, 39
    int 0x80

    ; Read second binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number2
    mov edx, 17
    int 0x80

    ; Perform the logical XOR operation
    xor ebx, ebx
    xor esi, esi
    
    xor_loop:
        mov al, byte [bin_number1 + ebx]
        xor al, byte [bin_number2 + ebx]
        mov [bin_number1 + esi], al
        inc ebx
        inc esi
        cmp ebx, 4   ; Only 4 bits needed for the XOR operation
        jne xor_loop
        
      
    ; Display the result
    mov eax, 4
    mov ebx, 1
    mov ecx, bin_number2
    mov edx, 4
    int 0x80

    ; Print two newlines
    mov eax, 4
    mov ebx, 1
    mov ecx, double_newline
    mov edx, 2
    int 0x80

    jmp _start
    
NOT_operation:
    ; Prompt for the binary number
    mov eax, 4
    mov ebx, 1
    mov ecx, bin1_prompt
    mov edx, 38
    int 0x80

    ; Read the binary number
    mov eax, 3
    mov ebx, 0
    mov ecx, bin_number1
    mov edx, 8
    int 0x80

    ; Perform NOT operation
    mov esi, bin_number1
    mov ecx, 8            ; Iterate through each bit
    perform_not_loop:
        xor byte [esi], 1      ; XOR each bit with 1 to perform NOT operation
        inc esi               ; Move to the next bit
        loop perform_not_loop
    
        ; Display the result
        mov eax, 4
        mov ebx, 1
        mov ecx, bin_number1
        mov edx, 8
        int 0x80
    
        ; Print two newlines
        mov eax, 4
        mov ebx, 1
        mov ecx, double_newline
        mov edx, 2
        int 0x80
    
        jmp _start    
 

Assembly Online Compiler

Write, Run & Share Assembly code online using OneCompiler's Assembly online compiler for free. It's one of the robust, feature-rich online compilers for Assembly language. Getting started with the OneCompiler's Assembly compiler is simple and pretty fast. The editor shows sample boilerplate code when you choose language as Assembly and start coding.

About Assembly

Assembly language(asm) is a low-level programming language, where the language instructions will be more similar to machine code instructions.

Every assembler may have it's own assembly language designed for a specific computers or an operating system.

Assembly language requires less execution time and memory. It is more helful for direct hardware manipulation, real-time critical applications. It is used in device drivers, low-level embedded systems etc.

Syntax help

Assembly language usually consists of three sections,

  1. Data section

    To initialize variables and constants, buffer size these values doesn't change at runtime.

  2. bss section

    To declare variables

  3. text section

    _start specifies the starting of this section where the actually code is written.

Variables

There are various define directives to allocate space for variables for both initialized and uninitialized data.

1. To allocate storage space to Initialized data

Syntax

variable-name    define-directive    initial-value 
Define DirectiveDescriptionAllocated Space
DBDefine Byte1 byte
DWDefine Word2 bytes
DDDefine Doubleword4 bytes
DQDefine Quadword8 bytes
DTDefine Ten Bytes10 bytes

2. To allocate storage space to un-initialized data

Define DirectiveDescription
RESBReserve a Byte
RESWReserve a Word
RESDReserve a Doubleword
RESQReserve a Quadword
RESTReserve a Ten Bytes

Constants

Constants can be defined using

1. equ

  • To define numeric constants
CONSTANT_NAME EQU regular-exp or value

2. %assign

  • To define numeric constants.
%assign constant_name value

3. %define

  • To define numeric or string constants.
%define constant_name value

Loops

Loops are used to iterate a set of statements for a specific number of times.

mov ECX,n
L1:
;<loop body>
loop L1

where n specifies the no of times loops should iterate.

Procedures

Procedure is a sub-routine which contains set of statements. Usually procedures are written when multiple calls are required to same set of statements which increases re-usuability and modularity.

procedure_name:
   ;procedure body
   ret