I'm trying to write a simple assembly language code. It runs but is having slight issues.
The code is meant to accept five values and to store in an array, therefore it prompts the user five times. Whenever it prompts the user in a newline the printed prompts is shifted leftward to the previous line. In the end the last lines are cut out from view. Also the code is not printing my answer right, instead it prints the previous value in the register. Also the resulting value in the register is not correlating
TITLE ArraySumInput X (ArraySumInput.asm)
; A program calculating the sum of an array with user input
; Yemi
; 8th December, 2023
org 100h
.DATA
array_size DW 5
array DW 5 DUP ?
sum DW ?
prompt_msg DB " Enter an integer: $"
ans_msg DB "Answer is "
newline_msg DB 13, 10, "$" ; Newline characters for formatting
.CODE
main PROC
; Accept input for the array elements
mov cx, array_size ; Set the loop counter to the array size
lea si, array ; Load the address of the array into si
input_loop:
mov ah, 09 ; DOS function to print a string
lea dx, newline_msg ; Load the address of the newline characters
int 21h ; DOS interrupt to invoke the function
mov ah, 09 ; DOS function to print a string
lea dx, prompt_msg ; Load the address of the prompt message
int 21h ; DOS interrupt to invoke the function
mov ah, 0Ah ; DOS function to input a string
lea dx, [si] ; Load the address where the input will be stored
int 21h ; DOS interrupt to invoke the function
; Convert the input to a number
mov ax, [si+2] ; Move the ASCII digits to ax
sub ax, '0' ; Convert ASCII to integer
mov [si], ax ; Store the integer in the array element
add si, 2 ; Move to the next element in the array (assuming 16-bit integers)
loop input_loop ; Repeat until cx (loop counter) is zero
; Calculate the sum of the array
mov cx, array_size ; Reset the loop counter
lea si, array ; Reset the address of the array into si
; Initialize sum to zero
mov sum, 0
sum_loop:
mov ax, [si] ; Load the current array element to ax
add sum, ax ; Add the current array element to the sum
add si, 2 ; Move to the next element in the array (assuming 16-bit integers)
loop sum_loop ; Repeat until cx (loop counter) is zero
; Print a newline
mov ah, 09 ; DOS function to print a string
lea dx, newline_msg ; Load the address of the newline characters
int 21h ; DOS interrupt to invoke the function
; Print the prompt message
mov ah, 09 ; DOS function to print a string
lea dx, ans_msg ; Load the address of the answer message
int 21h ; DOS interrupt to invoke the function
mov ah, 09 ; DOS function to print a string
lea dx, sum ; Load the address of the sum variable
int 21h ; DOS interrupt to invoke the function
main ENDP
END main
ret
I have tried adding a code to print new line and also made the code add the value at the memory address pointed by SI to the sum but they're not working.
I am using an emu8086 emulator on an X64 architecture.
mov ah, 0Ah ; DOS function to input a string lea dx, [si] ; Load the address where the input will be stored int 21h ; DOS interrupt to invoke the function
You don't pass the DOS.BufferedInput function 0Ah the correct input structure. Full info about this in How buffered input works.
Add next to your `.DATA. section:
sum DW ?
buf DB 3,0,0,0,0
and invoke DOS in the following manner:
mov bx, buf
mov dx, bx
mov ah, 0Ah
int 21h
cmp byte [bx+1], 2
jne input_loop
; Convert the input to a number mov ax, [si+2] ; Move the ASCII digits to ax sub ax, '0' ; Convert ASCII to integer mov [si], ax ; Store the integer in the array element
Trusting the user has input two decimal digits, this code only converts one of them into its value [0,9], moreover this code does not even start to combine the digits into the full number that they represent [0,99].
mov ax, [bx + 2] ; Load the 2 decimal characters
sub ax, '00' ; Convert both together (SWAR-style)
xchg al, ah ; Remember x86 is little-endian
aad ; -> AX = AH * 10 + AL
mov [si], ax ; Store in the array
mov ah, 09 ; DOS function to print a string lea dx, sum ; Load the address of the sum variable int 21h ; DOS interrupt to invoke the function
The DOS.PrintString function 09h only prints strings of text characters (and a few control codes like 10 and 13). Read all about it in Displaying characters with DOS or BIOS. Since at sum is stored a binary number [0,495], you first need to convert it into a string of characters. In Displaying numbers with DOS you'll find everything there is to know about this conversion.
Tip 1: You can easily do the summing within the input_loop. Then you don't need a separate loop for that. Add a line like:
mov [si], ax ; Store in the array
add sum, ax
Tip 2: You can improve displaying the result.
ans_msg DB "Answer is " newline_msg DB 13, 10, "$"
In ans_msg that final space character tells me that you really would like to see the result on the same line. Because there is no $ character, the newline_msg that follows gets appended. Better write:
ans_msg DB "Answer is $"
newline_msg DB 13, 10, "$"