I'm currently working on an Assembly x86 tasm language program for task management that allows adding and viewing tasks. However, I've been struggling to implement a function to delete a specific task.
.model small
.stack 100h
.data
sir db 80 dup('$')
m2 db 'Introduceti sirul:$'
m4 db '1. Add task', 13, 10, '$'
m5 db '2. View tasks', 13, 10, '$'
filename db 'tasks.txt',0
handle dw ?
strLength dw ?
t_handle dw ?
newline db 13, 10, '$' ; New line characters
menuChoice db ?
buffer db 2000 dup(0)
.code
mov ax,@data
mov ds,ax
mov ah, 9h
mov dx, offset m4
int 21h
mov ah, 9h
mov dx, offset m5
int 21h
mov ah, 1h
int 21h
mov menuChoice, al
cmp menuChoice, '1'
je add_task
cmp menuChoice, '2'
je view_tasks
cmp menuChoice, '3'
je delete_aux
jmp end_program
view_tasks:
; Opening file for reading
mov ah, 3Dh
mov al, 0
mov dx, offset filename
int 21h
mov handle, ax
; Reading file contents
mov ah, 3Fh
mov bx, handle
mov dx, offset sir
mov cx, 80
int 21h
; Displaying tasks line by line with incrementing numbers
mov si, offset sir
display_loop:
; Check if end of file or end of buffer
cmp byte ptr [si], '$'
je end_display
; Print character to screen
mov ah, 02h
mov dl, [si]
int 21h
; Move to the next character
inc si
jmp display_loop
end_display:
; Close the file
mov ah, 3Eh ; File close service
mov bx, handle ; File handle
int 21h ; File close interrupt
jmp end_program
delete_aux:
cmp menuChoice, '3' ; Check if the choice is for delete
jne view_tasks ; If not, jump to view_tasks
jmp delete_task ; If yes, jump to delete_task
add_task:
; Clearing the buffer
mov ah, 0Ah
mov dx, offset sir
int 21h
; Adding a task to the file
; Prompting for task input
mov ah, 9h
mov dx, offset m2
int 21h
mov bx,0
mov cx,80
mov ah,3fh
mov dx,offset sir
int 21h
mov ah, 9h
mov dx, offset sir
int 21h
; Calculating string length
mov si, offset sir
add si, 2
mov cx, 0 ; Initialize count
count_length:
cmp byte ptr [si], '$'
je end_count
inc cx
inc si
jmp count_length
end_count:
mov strLength, cx
; Opening file for appending at the end
mov ah, 3Dh
mov al, 2 ;
mov dx, offset filename
int 21h
mov handle, ax
; Positioning at the end of the file
mov ah, 42h
mov al, 2
mov bx, handle
mov cx, 0
mov dx, 0
int 21h
; Writing string to file
mov ah, 40h
mov bx, handle
mov dx, offset sir
mov cx, strLength
int 21h
; Writing newline to file
mov ah, 40h
mov bx, handle
mov dx, offset newline
mov cx, 2
int 21h
; Closing the file
mov ah, 3Eh
mov bx, handle
int 21h
jmp view_tasks
delete_task:
jmp view_tasks ; Redirect to view tasks after deletion
end_program:
mov ah,4Ch
int 21h
end
I've tried implementing a 'Delete task' option and managed file operations using termination characters 13, 10, '$', but I can't get the hang of it.
delete_task:
; Prompt for task number to delete
mov ah, 9h
mov dx, offset m_delete_prompt
int 21h
; Read user input for the task number to delete
mov ah, 1h
int 21h
sub al, '0'
mov bl, al
; Opening the file for reading and writing
mov ah, 3Dh
mov al, 2
mov dx, offset filename
int 21h
mov handle, ax
; Reading and deleting the desired task
mov ah, 3Fh
mov bx, handle
mov dx, offset buffer
mov cx, 2000
int 21h
mov si, offset buffer
mov di, si
delete_loop:
cmp byte ptr [si], '$'
je end_delete
mov al, [si]
cmp al, 13
je check_next_char
mov [di], al
inc di
inc si
jmp delete_loop
check_next_char:
inc si ; Move to next character (LF)
mov al, [si]
cmp al, 10
je delete_task_found
mov byte ptr [di], 13
inc di
mov [di], al
inc di
inc si
jmp delete_loop
delete_task_found:
; Check if it's the desired task to delete
sub al, '0'
cmp al, bl
je skip_task
jmp copy_task
skip_task:
; Skip the task to delete
mov al, [si]
cmp al, 13
jne skip_task
jmp delete_loop
copy_task:
; Copy the task to keep it
mov [di], al
inc di
inc si
jmp delete_loop
end_delete:
; Truncate the file at the updated position
mov ah, 40h
mov bx, handle
mov dx, offset buffer
sub di, offset buffer
int 21h
; Close the file
mov ah, 3Eh
mov bx, handle
int 21h
jmp view_tasks
; Data Section
m_delete_prompt db 'Enter the task number to delete: $'
For the following tasks:
task1
task2
task3
task4
task5
This is what I got:
task1
task2
task3
task4
task5
task1Útask2Útask3Útask4Útask5Ú ÿÿùtâ
As I said in comment above, the number of task for deletion should be saved. So push bx
does the job. Restore this value by using pop bx
before delete_loop:
.
This instruction cmp byte ptr [si], '$'
at the begining of delete_loop
searches for $
but buffer
is filled with 0
's. So this loop could run forever
unless somewhere in memory there is $
. So either fill buffer with $
or add variable eotb db '$'
after buffer
to mark end of the buffer.
What is going on inside delete_loop
is this..
0d
go to check_next_char:
0a
go to delete_task_found:
al = 0a
, so this instruction sub al '0'
doesn't substract '0'
from '1' - '9'
to get proper task numbert
,a
,s
,k
,1 - 9
are skippedI can propose this solution...
Each record in file looks like this task 1-9 0d 0a
First number of the task is at location buffer + 4
Next are every 7 bytes:
buffer + 4 + 7
buffer + 4 + 7 + 7
buffer + 4 + 7 + 7 + 7
buffer + 4 + 7 + 7 + 7 ...
If program finds number of the task in file it modifies buffer and writes new data to file
else $
means there is no task in file.
I wrote code just for deleting tasks
.model small
.stack 100h
.data
sir db 80 dup('$')
m2 db 'Introduceti sirul:$'
m4 db '1. Add task', 13, 10, '$'
m5 db '2. View tasks', 13, 10, '$'
m6 db '3. Del tasks', 13, 10, '$'
filename db 'code60t.txt',0
filesize dw ?
handle dw ?
strLength dw ?
t_handle dw ?
newline db 13, 10, '$' ; New line characters
menuChoice db ?
buffer db 70 dup('$')
m_delete_prompt db 13,10,'Enter the task number to delete: $'
task_doesnt_exists db 13,10,'This task is not in the file.',13,10,'$'
del_task db 13,10,'Deleting task number $'
.code
start:
mov ax,@data
mov ds,ax
mov ah, 9h
mov dx, offset m4
int 21h
mov ah, 9h
mov dx, offset m5
int 21h
mov ah, 9h
mov dx, offset m6
int 21h
mov ah, 1h
int 21h
mov menuChoice, al
mov ah, 9h
mov dx, offset newline
int 21h
cmp menuChoice, '1'
je add_task
cmp menuChoice, '2'
je view_tasks
cmp menuChoice, '3'
je delete_aux
jmp end_program
view_tasks:
; Opening file for reading
mov ah, 3Dh
mov al, 2
mov dx, offset filename
int 21h
mov handle, ax
; Reading file contents
mov ah, 3Fh
mov bx, handle
mov dx, offset sir
mov cx, 80
int 21h
; Displaying tasks line by line with incrementing numbers
mov si, offset sir
display_loop:
; Check if end of file or end of buffer
cmp byte ptr [si], '$'
je end_display
; Print character to screen
mov ah, 02h
mov dl, [si]
int 21h
; Move to the next character
inc si
jmp display_loop
end_display:
; Close the file
mov ah, 3Eh ; File close service
mov bx, handle ; File handle
int 21h ; File close interrupt
jmp end_program
delete_aux:
cmp menuChoice, '3' ; Check if the choice is for delete
jne view_tasks ; If not, jump to view_tasks
jmp delete_task ; If yes, jump to delete_task
add_task:
; Clearing the buffer
mov ah, 0Ah
mov dx, offset sir
int 21h
; Adding a task to the file
; Prompting for task input
mov ah, 9h
mov dx, offset m2
int 21h
mov bx,0
mov cx,80
mov ah,3fh
mov dx,offset sir
int 21h
mov ah, 9h
mov dx, offset sir
int 21h
; Calculating string length
mov si, offset sir
add si, 2
mov cx, 0 ; Initialize count
count_length:
cmp byte ptr [si], '$'
je end_count
inc cx
inc si
jmp count_length
end_count:
mov strLength, cx
; Opening file for appending at the end
mov ah, 3Dh
mov al, 2 ;
mov dx, offset filename
int 21h
mov handle, ax
; Positioning at the end of the file
mov ah, 42h
mov al, 2
mov bx, handle
mov cx, 0
mov dx, 0
int 21h
; Writing string to file
mov ah, 40h
mov bx, handle
mov dx, offset sir
mov cx, strLength
int 21h
; Writing newline to file
mov ah, 40h
mov bx, handle
mov dx, offset newline
mov cx, 2
int 21h
; Closing the file
mov ah, 3Eh
mov bx, handle
int 21h
jmp view_tasks
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
delete_task:
; Prompt for task number to delete
mov ah, 9h
mov dx, offset m_delete_prompt
int 21h
; Read user input for the task number to delete
mov ah, 1h
int 21h
mov bl, al
push bx ; save the number of the task
;---- file operations
; Opening the file for reading and writing
mov ah, 3Dh
mov al, 2
mov dx, offset filename
int 21h
mov handle, ax
; Reading from file to buffer
mov ah, 3Fh
mov bx, handle
mov dx, offset buffer
mov cx, 70
int 21h
; calculate file size, this value is used later
mov ah,42h
mov al,2
xor cx,cx
xor dx,dx
int 21h
mov filesize, ax
; close file, later program uses 3ch because we want to delete old data in file and write modified data
mov ah, 3eh
int 21h
;---- buffer operations
mov si, offset buffer
add si, 4 ; first location of the task number
pop bx ; restore the number of task
delete_loop:
cmp byte ptr [si],'$' ; check if we reached end of buffer
je no_tasks
mov al, [si] ; task number
cmp al, bl ; is this our task?
je task_found ; yes
add si, 7 ; no, go to next record
jmp delete_loop ; try again
task_found:
mov ah, 9h ; show some messages
mov dx, offset del_task
int 21h
mov ah, 2h
mov dl, bl
int 21h
mov ah, 9h
mov dx, offset newline
int 21h
add si, 3 ; start of the next record
mov di, si
sub di, 7 ; start of the record we want to delete
; do this by moving rest of the tasks up 7 bytes
mov al, 10 ; we can have max 9 tasks (9 * 7 bytes = 63) + 7 bytes of '$' to clear end of the list
mov ah, 0
sub bl, 30h
sub al, bl ; calculate how many bytes to copy
mov bl, 7
mul bl
mov cx, ax
tasks_move:
mov al, [si]
mov [di], al
inc si
inc di
dec cx
jnz tasks_move
write_to_file:
mov ah, 3ch
mov dx, offset filename
mov cx, 2
int 21h
; Writing modified buffer to file
mov bx, ax
mov ah, 40h
mov dx, offset buffer
mov cx, filesize
sub cx,7
int 21h
mov ah, 3eh
int 21h
jmp view_tasks
no_tasks:
mov ah, 9h
mov dx, offset task_doesnt_exists
int 21h
jmp view_tasks
end_program:
mov ah,4Ch
int 21h
end start