Assembly Language Array printing - arrays

I'm having a hard time with this homework assignment. I need to print my array showing that the numbers I pulled from ReadInt are in it. I'm not sure how to do that.
Here is my code so far.
.data
intarray DWORD ?
finish BYTE "Please enter a EVEN number less than 50. ", 0dh, 0ah, 0
finish2 BYTE "The entered array is: ", 0dh, 0ah, 0
finish3 BYTE "The sum of the first half of the array is: ", 0dh, 0ah, 0
finish4 BYTE "Please enter your numbers: ", 0dh, 0ah, 0
.code
main proc
mov edx, OFFSET finish
call WriteString
call crlf
call ReadInt
add intarray, eax
call crlf
mov edx, OFFSET finish4
call WriteString
call crlf
mov ecx,intarray
L1:
call ReadInt
mov intarray, eax
inc intarray
loop L1
mov edx, OFFSET finish2
call WriteString
call crlf
invoke ExitProcess,0
main endp
end main
I need to print my intarray to show that the number's entered by ReadInt are in it. I'm not sure how to do this.

Next code does what you need. The code was made with EMU8086 : it reads 10 numbers as strings (because data comes from keyboard), convert every string to number, insert them into the array, clears the screen, and displays the numbers in the array, converting every number to string (to display them). It's plenty of comments to help you understand (hope this helps you) :
.stack 100h
;------------------------------------------
.data
;------------------------------------------
array dw 10 dup(?)
msj db 13,10,'Enter a number: $'
str db 6 ;MAX NUMBER OF CHARACTERS ALLOWED (5).
db ? ;LENGTH (NUMBER OF CHARACTERS ENTERED BY USER).
db 6 dup (?) ;CHARACTERS ENTERED BY USER.
buf db 6 dup('$') ;WILL HOLD NUMBERS WITH 5 DIGITS OR LESS.
crlf db 13,10,'$'
count db ? ;JUST A COUNTER FOR LOOPS.
;------------------------------------------
.code
;INITIALIZE DATA SEGMENT.
mov ax, #data
mov ds, ax
;------------------------------------------
;CAPTURE 10 NUMBERS FROM USER.
mov di, offset array ;POINTER TO ARRAY.
mov count, 10 ;WE WILL CAPTURE 10 NUMBERS.
ten_numbers:
;DISPLAY MESSAGE.
mov ah, 9
mov dx, offset msj
int 21h
;CAPTURE NUMBER AS STRING.
mov ah, 0Ah
mov dx, offset str
int 21h
;CONVERT CAPTURED NUMBER FROM STRING TO NUMERIC.
mov si, offset str ;PARAMETER FOR STRING2NUMBER.
call string2number ;NUMBER RETURNS IN BX.
;INSERT NUMBER INTO ARRAY.
mov [ di ], bx ;NUMBER GOES IN CURRENT POSITION (DI).
add di, 2 ;ARRAY POSITION FOR THE NEXT NUMBER. MUST BE
;2 BECAUSE IT'S AN ARRAY OF DW (DW = TWO BYTES).
;REPEAT PROCESS.
dec count
jnz ten_numbers ;IF ( COUNT != 0 ) JUMP.
;------------------------------------------
;DISPLAY THE NUMBERS IN ARRAY.
call clear_screen
mov di, offset array
mov count, 10 ;ARRAY HAS 10 NUMBERS.
print_array:
;CONVERT NUMBER TO STRING TO DISPLAY IT.
call dollars ;FILLS BUF WITH DOLLARS (REQUIRED TO DISPLAY).
mov ax, [ di ] ;MOVE CURRENT NUMBER TO AX.
call number2string ;TAKES AX AS PARAMETER.
;STRING RETURNS IN VARIABLE BUF.
;DISPLAY STRING.
mov ah, 9
mov dx, offset buf
int 21h
;DISPLAY LINE BREAK.
mov ah, 9
mov dx, offset crlf
int 21h
;REPEAT PROCESS.
add di, 2 ;NEXT NUMBER IN ARRAY TO BE DISPLAYED. MUST BE
;2 BECAUSE IT'S AN ARRAY OF DW (DW = TWO BYTES).
dec count
jnz print_array ;IF ( COUNT != 0 ) JUMP.
;------------------------------------------
;WAIT FOR USER TO PRESS ANY KEY.
mov ah,7
int 21h
;------------------------------------------
;FINISH THE PROGRAM.
mov ax, 4c00h
int 21h
;==========================================
;NUMBER TO CONVERT MUST ENTER IN AX.
;ALGORITHM : EXTRACT DIGITS ONE BY ONE, STORE
;THEM IN STACK, THEN EXTRACT THEM IN REVERSE
;ORDER TO CONSTRUCT STRING (BUF).
proc number2string
mov bx, 10 ;DIGITS ARE EXTRACTED DIVIDING BY 10.
mov cx, 0 ;COUNTER FOR EXTRACTED DIGITS.
cycle1:
mov dx, 0 ;NECESSARY TO DIVIDE BY BX.
div bx ;DX:AX / 10 = AX:QUOTIENT DX:REMAINDER.
push dx ;PRESERVE DIGIT EXTRACTED FOR LATER.
inc cx ;INCREASE COUNTER FOR EVERY DIGIT EXTRACTED.
cmp ax, 0 ;IF NUMBER IS
jne cycle1 ;NOT ZERO, LOOP.
;NOW RETRIEVE PUSHED DIGITS.
mov si, offset buf
cycle2:
pop dx
add dl, 48 ;CONVERT DIGIT TO CHARACTER.
mov [ si ], dl
inc si
loop cycle2
ret
endp
;------------------------------------------
;CONVERT STRING TO NUMBER IN BX.
;SI MUST ENTER POINTING TO THE STRING.
proc string2number
;MAKE SI TO POINT TO THE LEAST SIGNIFICANT DIGIT.
inc si ;POINTS TO THE NUMBER OF CHARACTERS ENTERED.
mov cl, [ si ] ;NUMBER OF CHARACTERS ENTERED.
mov ch, 0 ;CLEAR CH, NOW CX==CL.
add si, cx ;NOW SI POINTS TO LEAST SIGNIFICANT DIGIT.
;CONVERT STRING.
mov bx, 0
mov bp, 1 ;MULTIPLE OF 10 TO MULTIPLY EVERY DIGIT.
repeat:
;CONVERT CHARACTER.
mov al, [ si ] ;CHARACTER TO PROCESS.
sub al, 48 ;CONVERT ASCII CHARACTER TO DIGIT.
mov ah, 0 ;CLEAR AH, NOW AX==AL.
mul bp ;AX*BP = DX:AX.
add bx,ax ;ADD RESULT TO BX.
;INCREASE MULTIPLE OF 10 (1, 10, 100...).
mov ax, bp
mov bp, 10
mul bp ;AX*10 = DX:AX.
mov bp, ax ;NEW MULTIPLE OF 10.
;CHECK IF WE HAVE FINISHED.
dec si ;NEXT DIGIT TO PROCESS.
loop repeat ;COUNTER CX-1, IF NOT ZERO, REPEAT.
ret
endp
;------------------------------------------
;FILLS VARIABLE BUF WITH '$'.
;USED BEFORE CONVERT NUMBERS TO STRING, BECAUSE
;THESE STRINGS WILL BE DISPLAYED.
proc dollars
mov si, offset buf
mov cx, 6
six_dollars:
mov al, '$'
mov [ si ], al
inc si
loop six_dollars
ret
endp
;------------------------------------------
proc clear_screen
mov ah,0
mov al,3
int 10H
ret
endp
Maybe it's important to explain a little the variable str, notice the three level format, it's using 3 DBs because ah=0Ah (capture string) requires it : the first DB must indicate the max number of characters allowed, a second DB is necessary to store the length, and the third DB are the characters themselves. The string ends with ENTER (character 13), that's why the first DB is 6 (if user enters 5 characters, the sixth is ENTER).

Related

How to write decimal number by one char to file 8086 YASM

I have a task and I will try to explain it clearly. There is a file with [0; 1000] lines. Each line contains 6 columns.
The first two columns contain string with [1; 20] characters. Characters could be letters, numbers, and whitespaces.
3-5 columns contain integers in the range [-100; 100].
6th column contain real numbers in range [-9.99; 9.99] with only two digits after decimal point.
Each section I separated by a semicolon ';'.
FILE EXAMPLE:
helloA;lB;lC;lD;lE;lF
A11;bas morning;0;0;5;1.15
B12; Hello WoRlD;-100;11;78;1.33
B11;table;10;0;55;-2.44
C1;OakWood;0;8;17;3.77
TASK: count how many lines in the first two sections contain the letters 'B' and 'C'. And print that integer number in the other file.
I did almost all the task, except one thing. I don't know how to print the decimal number in the file. I store this number in memory as hexadecimal. I need to convert that number to decimal and print it into the other file.
I am struggling because there could be 1 good line, but it also could be 1000 good lines. So I need to print 1 character (if the number of good lines is between [0; 9]), but it could be 900 good lines, so then the program has to print 3 characters.
MY CODE
org 100h
%include 'yasmmac.inc'
section .text
startas:
macPutString 'Output file:', crlf, '$'
; Save the writing file's name
mov al, 128
mov dx, writingFile
call procGetStr
macNewLine
; Open reading file
mov dx, readingFile
call procFOpenForReading
jnc .writingFileOpen
macPutString 'Error while opening the writing file!', '$'
exit
; Open the writing file
.writingFileOpen:
mov [readingDescriptor], bx
mov dx, writingFile
call procFCreateOrTruncate
jnc .writingFileSuccessfullyOpened
macPutString 'Error while opening file for writing!', '$'
jmp .writingError
; Sacing writing descriptor
.writingFileSuccessfullyOpened:
mov [writingDescriptor], bx
; Read first line
call procReadLine
; Main loop
.untilEndOfFile:
call procReadLine
; checking the first two columns
;mov al, ';'
; checking first column
.firstColumn:
mov al, [di]
inc di
cmp al, byte 'B'
je .skipALine
cmp al, byte 'b'
je .skipALine
cmp al, byte 'C'
je .skipALine
cmp al, byte 'c'
je .skipALine
cmp al, byte ';'
jne .firstColumn
; checking second column
.secondColumn:
mov al, [di]
inc di
cmp al, byte 'B'
je .skipALine
cmp al, byte 'b'
je .skipALine
cmp al, byte 'C'
je .skipALine
cmp al, byte 'c'
je .skipALine
cmp al, byte ';'
jne .secondColumn
jmp .addNumber ; Adding number because line corresponds to filter.
.addNumber:
call procAddNumber
; If it is not the end of file, jump back to main loop
.skipALine:
cmp [readTheLastLine], byte 0
je .untilEndOfFile
; Writing to file (number, how many good lines)
; **I cant do this part**
mov bx, [writingDescriptor]
mov cx, 2h
mov dx, lineCount
mov ah, 40h
int 21h
; Closing Files
.end:
mov bx, [writingDescriptor]
call procFClose
.writingError:
mov bx, [readingDescriptor]
call procFClose
exit
%include 'yasmlib.asm'
; void procReadLine()
; Read line to buffer 'line'
procReadLine:
push ax
push bx
push cx
push si
mov bx, [readingDescriptor]
mov si, 0
.loop:
call procFGetChar
; End if the end of file or error
cmp ax, 0
je .endOfFile
jc .endOfFile
; Putting symbol to buffer
mov [line+si], cl
inc si
; Check if there is \n?
cmp cl, 0x0A
je .endOfLine
jmp .loop
.endOfFile:
mov [readTheLastLine], byte 1
.endOfLine:
mov [line+si], byte '$'
mov [lineLength], si
pop si
pop cx
pop bx
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procAddNumber:
push si
push ax
push bx
push cx
push dx
;lineCount++
mov ax, [lineCount]
inc ax
mov [lineCount], ax
pop dx
pop cx
pop bx
pop ax
pop si
ret
section .data
readingFile:
db 'input.dat', 00
readingDescriptor:
dw 0000
writingFile:
times 128 db 00
writingDescriptor:
dw 0000
readTheLastLine:
db 00
line:
db 64
times 66 db '$'
lineLength:
dw 0000
lineCount:
dw 0000
GitHub link to macroses:
yasmlib.asm/yasmmac.inc
Any help would be appreciated.
I don't know how to print the decimal number in the file. I store this number in memory as hexadecimal. I need to convert that number to decimal and print it into the other file.
The solution to the problem is already in the yasmlib.asm file! It contains a code procUInt16ToStr that will convert the unsigned number in AX into an ASCIIZ string at the address in DX.
It does not return the length of the string, so you'll have to loop over the string and use procFPutChar to send the individual characters to the file. Alternatively and preferably loop over the string to establish the stringlength and output all at once with DOS function 40h (like you were doing already).
If you're interested in knowing how to convert from integer to string, then you could read my Q/A Displaying numbers with DOS.
.WritingToFile:
mov dx, Buffer
mov ax, [linecount]
call procUInt16ToStr ; produces an ASCIIZ string at DX
mov si, dx
.again:
lodsb
cmp al, 0
jne .again
sub si, dx
lea cx, [si - 1] ; -1 because we don't want to send the zero
mov bx, [writingDescriptor]
mov ah, 40h ; DOS.WriteToFile
int 21h ; -> AX CF
Watch out with these
.untilEndOfFile:
call procReadLine
.firstColumn:
mov al, [di]
This code is using DI without having initialized the register (mov di, line).
.skipALine:
cmp [readTheLastLine], byte 0
je .untilEndOfFile
Inspecting the readTheLastLine variable comes too late! You need this directly following the return from the procReadLine procedure:
.untilEndOfFile:
call procReadLine
cmp byte [readTheLastLine], 0
je .WritingToFile
mov di, line
.firstColumn:
mov al, [di]
...
jmp .untilEndOfFile
.WritingToFile:
You don't need that wasteful procAddNumber procedure to increment the linecount variable.
Simply replace call procAddNumber by inc word [linecount].
While the other answer dealt with your question about writing the textual representation of the number, this answer focusses on a fundamental misunderstanding about what the task is asking.
TASK: count how many lines in the first two sections contain the letters 'B' and 'C'
Your current program is counting the lines that neither contain a 'B' nor a 'C'. The opposite from what was asked. Next will give you the count of lines that either contain a 'B' or a 'C'.
.untilEndOfFile:
call procReadLine
cmp byte [readTheLastLine], 0
je .WritingToFile
...
jne .secondColumn
jmp .untilEndOfFile
.skipALine:
inc word [linecount]
jmp .untilEndOfFile
.WritingToFile:
Note that the above is still not literally "contain the letters 'B' and 'C'", it's more like "contain the letters 'B' or 'C'". But don't worry, a distinction that is very important in programming might not always be considered that important in day to day speech/writing.

Enter and Display a vector in x86 Assembly

I am trying to learn TASM Assembly and i need your help.
I made this code which introduces a vector from the keyboard and than it displays it on the screen with the elements sum. The problem is that when it displays it displays some weird characters but the sum works.
Hope you can help me
TITLE vectors
.model small
.stack 100H
.data
msg1 db 10,13,"Enter the lenght of the vector$"
msg2 db 10,13,"Enter the vector elements $"
msg4 db 10,13,"The sum is $"
msg3 db 10,13,"The entered vector is $"
msg5 db " $"
vector db 0
sum db 0
x db 0
.code
main PROC
MOV ax,#data
MOV ds,ax
MOV ah,9h
LEA dx, msg1
int 21h
MOV ah,1h
int 21h
LEA Si,vector
MOV cl , al
MOV x,al
SUB cl , 30h
MOV sum , 0
Introducere:
MOV ah, 9h
LEA dx, msg2
int 21h
MOV ah,1h
int 21h
SUB al,30h
MOV [Si] , al
ADD Si, 1
ADD suma,al
DEC cl
JNZ Introducere
JZ Afisare1
Afisare1:
MOV ah,9h
LEA dx, msg3
int 21h
MOV cl,x
SUB cl,30h
LEA Si,vector
JMP Afisare2
Afisare2:
MOV dx,[Si]
ADD dx,30h
MOV ah,2h
int 21h
LEA dx,msg5
int 21h
INC Si
DEC cl
JNZ Afisare2
JZ Afisare3
Afisare3:
MOV ah,9h
LEA dx,msg4
int 21h
MOV dl,sum
ADD dl,'0'
MOV ah,2h
int 21h
MOV ah,04ch
int 21h
main ENDP
END main
The problem is that when it displays it displays some weird characters but the sum works.
These weird characters come from the ommission of the required function number for displaying your msg5. Currently, instead of showing a nice separating space, you get output of the low byte from msg5's address.
MOV ah,2h
int 21h
LEA dx,msg5
<<<<< Here is missing `mov ah, 09h`
int 21h
vector db 0
sum db 0
x db 0
With this definition of vector you reserve just 1 byte to store your inputs. That's not enough! Since your entire program works with single digit numbers, the length of the vector could range from 1 to 9. Therefore you need to make this change:
vector db 9 dup (0) ;This reserves 9 bytes
sum db 0
x db 0
Since your entire program works with single digit numbers and that you output the sum as a single digit number also, you can not be too generous with the values for the inputted numbers. An example that will work follows:
Enter the lenght of the vector3 <<<<< You're missing a space character here!
Enter the vector elements 2
Enter the vector elements 5
Enter the vector elements 1
The entered vector is 2 5 1
The sum is 8

Assembly Language code to count different characters but when any counter exceeds 9, it prints different symbols instead of that specific number [duplicate]

I've written a pretty simple code in asm x8086 and I'm facing an error. If anyone could help me with a brief explanation I would greatly appreciate it.
IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
array db 10h, 04h, 04h, 04h, 04h, 04h, 04h, 04h, 04h, 04h
sum db 0
; --------------------------
CODESEG
start:
mov ax, #data
mov ds, ax
; --------------------------
xor cx, cx
mov al, 0
mov bx, offset array
StartLoop:
cmp cx, 10
jge EndLoop
add al, [bx]
add [sum],al
inc cx
inc bx
jmp StartLoop
EndLoop:
mov ah, 09h
int 21h
; --------------------------
exit:
mov ax, 4c00h
int 21h
END start
With the correction for the add to be replaced by mov as noted in your comment (Note that the line: add al, [bx] is actually mov al, [bx]) there's just the function call at the label EndLoop that's wrong!
You want to display the sum, and are using the DOS print function. This function 09h expects a pointer in DS:DX that you are not providing!
Even if you did, you would still have to convert the sum number in its text representation.
A quick solution here would be to content yourself and just display the result in the form of a single ASCII character. The hardcoded sum is 52 and so it is a displayable character:
EndLoop:
mov dl, [sum]
mov ah, 02h ;Single character output
int 21h
; --------------------------
exit:
mov ax, 4c00h
int 21h
One step further and we can display "52":
mov al,[sum]
mov ah,0
mov dl,10
div dl ---> AL=5 AH=2
add ax,3030h ---> AL="5" AH="2"
mov dh,ah ;preserve AH
mov dl,al
mov ah,02h
int 21h
mov dl,dh ;restore
int 21h
I don't see any error at all, the code will sum the array, display some random sh*t, and exit.
You probably want to display result of sum?
int 21h, ah=9 will display '$' terminated string from memory pointed to by dx.
So you need two things, convert the number in [sum] to string terminated by'$' at end, and then set dx to the converted string ahead of that int 21h.
You may try to extract number2string procedure from here: https://stackoverflow.com/a/29826819/4271923
I would personally change it to take the address of target buffer in si as another call argument (ie. just remove the mov si,offset str from the procedure body). Like this:
PROC number2string
; arguments:
; ax = unsigned number to convert
; si = pointer to string buffer (must have 6+ bytes)
; modifies: ax, bx, cx, dx, si
mov bx, 10 ; radix 10 (decimal number formatting)
xor cx, cx ; counter of extracted digits set to zero
number2string_divide_by_radix:
; calculate single digit
xor dx, dx ; dx = 0 (dx:ax = 32b number to divide)
div bx ; divide dx:ax by radix, remainder will be in dx
; store the remainder in stack
push dx
inc cx
; loop till number is zero
test ax, ax
jnz number2string_divide_by_radix
; now convert stored digits in stack into string
number2string_write_string:
pop dx
add dl, '0' ; convert 0-9 value into '0'-'9' ASCII character encoding
; store character at end of string
mov [si], dl
inc si
; loop till all digits are written
dec cx
jnz number2string_write_string
; store '$' terminator at end
mov BYTE PTR [si],'$'
ret
ENDP
Then to call this at your EndLoop you need to add into data segment numberStr DB 8 DUP (0) to have some memory buffer allocated for string and add into code:
; load sum as 16b unsigned value into ax
xor ax,ax ; ax = 0
mov al,[sum] ; ax = sum (16b zero extended)
; convert it to string
mov si,OFFSET numberStr
call number2string
; display the '$' terminated string
mov dx,OFFSET numberStr
mov ah,9
int 21h
; ... exit ...

Assembly programing bug

I'm new at programming assembly. Now I'm trying to write a program that converts number from decimal to binary. But I got stuck with one program while trying to input. After i output msg2 and get into loop, program doesn't turn off. I can input a lot of numbers and program doesn't turn off. I guess problem is in convertnumber: cmp si,cx (si is how many numbers I have to input, cx- how many numbers I have already written), but I am not sure about that. Where have I made a mistake and how could I correct it?
.MODEL small
.Stack 100h
.DATA
msg0 db 'how many numbers will include your input number(example. 123 is 3 numbers)? $'
msg1 db 'Now input number from 0 to 65535: $'
number db 255, ?, 256 dup ('$')
numberinAscii db 255, ?, 256 dup ('$')
enterbutton db 13,10,'$'
.CODE
start:
mov ax, #data
mov ds,ax
mov ah,09h
mov dx, offset msg0 ; first message output
int 21h
xor ah,ah ; function 00h of
int 16h ; int 16h gets a character (ASCII translation in AL)
int 3
mov bl,al
mov dl,al
mov ah,02h ; function 02h - display character
int 21h ; call DOS service
mov ah,09h
mov dx, offset enterbutton
int 21h
mov ah, 09h
mov dx, offset msg1 ; output second message
int 21h
jmp covertHowMany ; converting number that we entered
next:
xor si,si
mov si, ax ; number that we entered now is in si
xor cx,cx
mov cx,0 ;cx=0
enterfirstnumber: ;entering first number (example 123, first number is 1)
xor ah,ah
int 16h ; int 16h gets a one character
int 3
mov bl,al
mov dl,al
mov ah,02h ; function 02h - display character
int 21h ;
jmp convertnumber ; converting this number
input: ;converting number from ascii char to ascii integer
mov ax,bx
mov dx,10
mul dx ; ax:=ax*10
mov bx,ax ; number that I try to convert is in bx now
xor ah,ah
int 16h ; int 16h gets a character (ASCII translation in AL)
int 3
mov bl,al
mov dl,al
mov ah,02h ; function 02h - display character
int 21h
jmp convertnumber
convertHowMany:
sub al,30h ; convert from ascii character to ascii number
jmp next
convertnumber:
sub al,30h
add bx,ax
inc cx
cmp cx, si
jne input
jmp ending
ending:
mov ax,04C00h
int 21h
end start
I see at least two problems with your code:
The first is that when you reach convertHowMany you assume that AL still contains the character that the user typed in. That will not be the case, since both INT 21h/AH=02h and INT 21h/AH=09h modify AL. You'll have to save and restore the value of AL somehow (e.g. by pushing and popping AX).
The second problem is how you initialize SI before the loop. You're moving the value of AX into SI, which means both AL and AH. AH is not zero at that point, because you've just used INT 21h/AH=09h.
You could change the sequence xor si,si / mov si,ax into something like mov si,ax / and si,0FFh.

Increment an array in assembly

Coding an assembly program to be used as a dictionary. User gives in the word and the program checks whether that word is present or not. TASM, 16 bit. Program works perfect for the first two elements of the array but if I provide balls. , the 3rd element of the array, even though the next element of array is being chosen, (verified on emu8086, bx becomes 007ch,->refer to code<-), the repe cmpsb still finishes its check after a single try. works properly with the first two elements of the array. Here is my code
The program firsts checks the length and later the bits. Length check is ended when a period (.) is provided.
.model large
.data
arrayele db 00d ;to count if all elements of the array have been compared with
count db 00d ;length of input count
nl db 10d,13d,'$' ;newline
mne db "Not Equal$" ;message if not equal
me db "Equal$" ;message if equal
buf db 99,?,99 dup(?) ;buffer where the input will be saved
w0 db "hello$" ;word 0-5
w1 db "which$"
w2 db "balls$"
w3 db "table$"
w4 db "chair$"
w5 db "apples$"
words dw offset w0,offset w1 ;the array
dw offset w2,offset w3
dw offset w4,offset w5
.code
main proc
mov ax,#data
mov ds,ax
mov es,ax
;take user input
mov ah,0ah
mov dx,offset buf
int 21h
;print new line
mov ah,09h
mov dx,offset nl
int 21h
;load input to di
mov di,offset buf
add di,2
;//saving length to a variable
repeat:
mov al,[di]
inc count
cmp al,"."
je lenchck
inc di
jmp repeat
;//end saving
lenchck:
dec count ;as full stop (period) (.) is also included in the count
stringmatch1:
mov cx,0 ;reset register
mov arrayele,0 ;reset variable
stringmatch:
mov di,offset buf ;loading input to di
add di,2
;loading array element to si
mov bx,0
mov bl,byte ptr words
mov si,bx ;end loading array element to si
mov cl,count
repe cmpsb
je equal
inc arrayele
inc words ;next word in the array
mov bx,0 ;loading it
mov bl,byte ptr words
mov si,bx ;end loading
cmp arrayele,06d ;compare to check if all elements have been compared with
jg wrong
jmp stringmatch
wrong: ;load notequal message
mov dx,offset mne
jmp print
equal:
mov dx,offset me ;load equal message
print:
mov ah,09h ;print it
int 21h
mov ah,4ch ;exit the program
int 21h
main endp
end main
inc words ;next word in the array
No, sorry. You've incremented (what was) the offset of w0. You haven't moved to the next word in the array. You want something more like...
mov bx, offset words
top:
; get offset of a string
mov si, [bx]
; do your comparison
; start at beginning of input every time
mov di, offset buf + 2 ; don't need a separate operation
mov cl, count ; (are we sure ch is clear?)
repe cmpsb
je found
; no? get next offset in words array
add bx, 2
jmp top
In your loop where you look for the '.', what's going to happen if the pesky user doesn't enter a '.'? The second byte in your input buffer (buf + 1), after the interrupt returns, is the count actually entered. It includes the '.' (if there was one) and the Carriage Return (13 or 0Dh) that ended input. You may be able to use this information to rule out obviously incorrect input.

Resources