我目前正在开发一个用于任务管理的 Assembly x86 tasm 语言程序,该程序允许添加和查看任务。然而,我一直在努力实现删除特定任务的功能。
.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
我尝试过使用终止符 13、10、'$' 来实现“删除任务”选项和托管文件操作,但我无法掌握其中的窍门。
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: $'
对于以下任务:
task1
task2
task3
task4
task5
这就是我得到的:
task1
task2
task3
task4
task5
task1Útask2Útask3Útask4Útask5Ú ÿÿùtâ
正如我在上面的评论中所说,应该保存要删除的任务数量。所以
push bx
就可以完成这项工作。在 pop bx
之前使用 delete_loop:
恢复此值。
这条指令
cmp byte ptr [si], '$'
位于delete_loop
的开头,搜索$
,但buffer
充满了0
。所以这个循环可以永远运行
除非记忆中某个地方有$
。因此,要么用 $
填充缓冲区,要么在 eotb db '$'
之后添加变量 buffer
以标记缓冲区的末尾。
里面发生的事情
delete_loop
是这样的..
0d
则转到 check_next_char:
0a
则转到 delete_task_found:
al = 0a
,所以这条指令sub al '0'
不会从'0'
中减去'1' - '9'
来获得正确的任务编号t
、a
、s
、k
、1 - 9
被跳过我可以提出这个解决方案...
文件中的每条记录如下所示
task 1-9 0d 0a
任务的第一个号码位于位置
buffer + 4
接下来是每7个字节:
buffer + 4 + 7
buffer + 4 + 7 + 7
buffer + 4 + 7 + 7 + 7
buffer + 4 + 7 + 7 + 7 ...
如果程序在文件中找到任务的编号,它会修改缓冲区并将新数据写入文件 否则
$
表示文件中没有任务。
我编写的代码只是为了删除任务
.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
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```