scrienume label let's me read from the keyboard 5 char names.The lista label displays each on one line along with their index(eg:if i write "daria" and "adria", the output is "1.daria", and on the next line is "2.maria"). The 3rd label should give me the possibility to write an index number from the keyboard and delete that has that index(eg:if i press 1 the name "daria" is deleted and the name "maria" gets the index 1).
These are the labels for input and output.
I tried to see in my program the location where i find the location of the index written from the keyboard and then move to the left in the string all the names that have an index bigger than the index i wrote.My problem is that my names are not being deleted from the list.This should erase a name from the list by id
scrienume:
mov dx, offset prompt
mov ah, 09h
int 21h
mov cx, 5
mov si, numePointer
read_char:
mov ah, 01h
int 21h
mov [si], al
inc si
loop read_char
mov byte ptr [si], '$'
inc si
mov numePointer, si ; numePointer = 6
jmp bucla
lista:
mov dx, offset nume
print_names:
push dx ; (1)
mov dx, offset numeIndex
mov ah, 09h
int 21h
inc byte ptr [numeIndex 2] ; "1" -> "2" -> "3" ...
pop dx ; (1)
mov ah, 09h
int 21h
add dx, 5 1
cmp dx, numePointer ; check if the current name is the last one
jb print_names
jmp bucla ; return to main loop
sterge:
; Prompt user for index of name to delete
mov dx, offset string
mov ah, 09h
int 21h
; Read index from user
mov ah, 01h
int 21h
sub al, '0'
mov al, al
mov bx, ax;
; Verify that index is valid
cmp bx, numes
jae invalidIndex
; Shift names to the left
mov cx, numes
mov si, numePointer
add si, bx
add si, bx
add si, bx
add si, bx
add si, bx
add si, 1
mov di, si
dec bx
dec numes
shiftLoop:
cmp bx, 0
je updatePointer
mov al, [si]
mov [di], al
inc si
inc di
dec bx
jmp shiftLoop
updatePointer:
mov numePointer, di
jmp bucla
invalidIndex:
; Display error message
mov dx, offset invalid
mov ah, 09h
int 21h
jmp bucla
CodePudding user response:
Troubles in sterge
sub al, '0' mov al, al mov bx, ax; cmp bx, numes jae invalidIndex
The way this is written, it will always jump to invalidIndex. Apparantly your numes (names in the list) variable is word-sized and you would like to extend the byte-sized response from the user to a full word. mov al, al
does not do that, you need mov ah, 0
(or cbw
for these very small positive numbers).
For a solution consider this: although the user will work with indexes starting at 1, the program should be using 0 as the first index as it will simplify things a lot.
sub al, '0' ; AL=[1,9]
cbw ; AX=[1,9] 1-based index
dec ax ; AX=[0,8] 0-based index
cmp ax, numes ; numes is [0,9]
jae invalidIndex
mov di, si
You are setting up for your shiftloop with identical pointers for the source and the destination! Any work the loop might do will not matter that way!
mov si, numePointer
You are not using the numePointer the way I defined and used it in my previous answer(s).
This is a pointer that contains the address of the end of the list of names.
elena$maria$daria$adria$
^ ^
nume [numePointer]
shiftLoop: cmp bx, 0 je updatePointer
You are using the index in BX to control the number of iterations. Each of your iterations just moves a single byte where in fact you should be moving 6 bytes (5 1), so you're copying not nearly enough!
Solution for sterge
Let's assume there are 4 names on the list, so numes=4:
1.elena
2.maria
3.daria
4.adria
Valid user inputs would be 1, 2, 3, and 4 and the validation code will turn this into AL ranging from 0 to 3.
Multiplying this number by 6 will give us the offset in the list where we find the name that is to be deleted. The part of the list that needs to be shifted down in memory then starts 6 bytes above that. It is possible for this part to be empty if the topmost item was selected for deletion. My code below uses the rep movsb
instruction that will work fine even if there's nothing to copy.
...
sub al, 49 ; AL=["1","9"] 1-based input -> AL=[0,8] 0-based index
mov ah, 6
mul ah ; -> AX = {0,6,12,18,24,30,36,42,48}
add ax, offset nume
cmp ax, numePointer
jnb invalidIndex
mov di, ax
lea si, [di 6]
mov cx, numePointer
sub cx, si
cld
rep movsb
mov numePointer, di
dec numes
jmp bucla
...
Beware of this: after deletion of a name you will probably want to use lista again. Make sure you reset the numeIndex to "1". Otherwise my code from I have an indexing problems won't function as it should:
lista:
mov byte ptr [numeIndex 2], "1"
...