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 bxdoes the job. Restore this value by usingpop bxbeforedelete_loop:.This instruction
cmp byte ptr [si], '$'at the begining ofdelete_loopsearches for$butbufferis filled with0's. So this loop could run forever unless somewhere in memory there is$. So either fill buffer with$or add variableeotb db '$'afterbufferto mark end of the buffer.What is going on inside
delete_loopis this..0dgo tocheck_next_char:0ago todelete_task_found:al = 0a, so this instructionsub al '0'doesn't substract'0'from'1' - '9'to get proper task numbert,a,s,k,1 - 9are skippedI can propose this solution...
Each record in file looks like this
task 1-9 0d 0aFirst number of the task is at location
buffer + 4Next are every 7 bytes:
buffer + 4 + 7buffer + 4 + 7 + 7buffer + 4 + 7 + 7 + 7buffer + 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