在Assembly x86 tasm中实现任务删除功能

问题描述 投票:0回答:1

我目前正在开发一个用于任务管理的 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â
assembly file-io x86 file-handling tasm
1个回答
0
投票
  1. 正如我在上面的评论中所说,应该保存要删除的任务数量。所以

    push bx
    就可以完成这项工作。在
    pop bx
    之前使用
    delete_loop:
    恢复此值。

  2. 这条指令

    cmp byte ptr [si], '$'
    位于
    delete_loop
    的开头,搜索
    $
    ,但
    buffer
    充满了
    0
    。所以这个循环可以永远运行 除非记忆中某个地方有
    $
    。因此,要么用
    $
    填充缓冲区,要么在
    eotb db '$'
    之后添加变量
    buffer
    以标记缓冲区的末尾。

  3. 里面发生的事情

    delete_loop
    是这样的..

    • 如果字节是
      0d
      则转到
      check_next_char:
    • 如果字节是
      0a
      则转到
      delete_task_found:
    • al = 0a
      ,所以这条指令
      sub al '0'
      不会从
      '0'
      中减去
      '1' - '9'
      来获得正确的任务编号
    • 其他字符
      t
      a
      s
      k
      1 - 9
      被跳过
  4. 我可以提出这个解决方案...

    • 文件中的每条记录如下所示

      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 ...

    • 如果程序在文件中找到任务的编号,它会修改缓冲区并将新数据写入文件 否则

      $
      表示文件中没有任务。

  5. 我编写的代码只是为了删除任务

    .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```
    
    
    
    
    
    
    
© www.soinside.com 2019 - 2024. All rights reserved.