在程序集中保存更改的文件(emu8086)

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

我需要在整个文件中用我的名字替换用户从键盘输入的文件中的特定字母,然后将其另存为新文件。

问题所在的代码部分。总是跳到错误,但是有了路径,一切都好了:

write_to_new_file:
    mov ah, 3Ch
    lea dx, new_file
    mov al, 0
    int 21h
    jc file_error
    mov bx, ax

这是代码的整个部分,我正在替换字母+尝试通过更改创建一个新文件:

org 100h

jmp start

; File paths
file1 db "c:\emu8086\vdrive\C\file1.txt", 0 ; and files 2 and 3 almost same paths
new_file db "c:\emu8086\vdrive\C\created_folder\file_corrected.txt", 0
handle dw ?

...

; General messages
...

; Replace functionality messages
...
start:
mov ax, cs
;mov dx, ax
mov es, ax
...
;********** REPLACEMENT ********************* 
    ; Create new file
    lea dx, new_file
    mov ah, 3Ch ; Create file function
    mov cx, 0   ; Normal attributes
    int 21h
    mov bx, ax ; Save handle of new file in BX
    
choose_file_for_replacement:
mov dx, offset replace_message ; Load address of footer
mov ah, 09h          ; DOS service to display string
int 21h              ; Call DOS interrupt

; Wait for user input
mov ah, 01h          ; DOS service to read character
int 21h              ; Call DOS interrupt
 
; Compare input directly with ASCII values for '1', '2', '3'
cmp al, '1'          ; Compare with '1'
je replace_file1
cmp al, '2'          ; Compare with '2'
je replace_file2
cmp al, '3'          ; Compare with '3'      
je replace_file3

replace_file1:
; Initialize data segment
    mov ax, @data
    mov ds, ax

    ; Open the file
    mov ah, 3Dh                ; Open file function
    mov al, 0                  ; Open for reading
    lea dx, file1              ; Load address of file name
    int 21h
    jc file_error              ; If error, jump to error handling
    mov bx, ax                 ; Store file handle in BX
    jmp read_into_buffer
    
replace_file2:
...
replace_file3:
...

read_into_buffer:
    mov ah, 3Fh                ; Read file function
    lea dx, buf                ; Load address of buffer
    mov cx, 255                ; Number of bytes to read
    int 21h
    jc file_error              ; If error, jump to error handling
    mov si, offset buf         ; SI points to the buffer

    ; Prompt user to enter the character to replace
    mov ah, 02h          ; DOS service to write character
    mov dx, offset prompt
    mov ah, 9
    int 21h

    ; Read the character from the user
    mov ah, 01h
    int 21h
    mov bl, al ; Store user input in BL
    mov ah, 02h          ; DOS service to write character

    ; Process the buffer
process_message:
    mov al, [si]
    cmp al, 0
    je write_to_new_file
    cmp al, bl
    jne skip_replacement

    ; Replace character with name
    mov di, offset replacement
output_replacement:
    mov al, [di]
    cmp al, 0
    je continue_processing
    mov dl, al
    mov ah, 2
    int 21h
    inc di
    jmp output_replacement

skip_replacement:
    mov dl, al
    mov ah, 2
    int 21h

continue_processing:
    inc si
    jmp process_message

write_to_new_file:
    mov ah, 3Ch
    lea dx, new_file
    mov al, 0
    int 21h
    jc file_error
    mov bx, ax

    ; Calculate the length of the modified buffer
    mov cx, si ; SI points to the end of the modified part

    ; Write the modified content to the new file
    mov ah, 40h
    lea dx, buf
    int 21h
    jc file_error

    ; Close the new file
    mov ah, 3Eh
    int 21h

    ; Display success message
    lea dx, success_message
    mov ah, 9
    int 21h
    jmp end_program

file_error:
    ; Display error message
    lea dx, message_error
    mov ah, 9
    int 21h
    jmp end_program
...

我尝试在互联网上查找有关此内容的一些信息,但找不到与保存现有文件的更改副本类似的内容

ps。如果需要代码的其他部分,请告诉我

assembly x86-16 emu8086
1个回答
0
投票

org 100h
jmp start
表示您正在创建 .COM 程序。这样的程序开始时所有段寄存器都彼此相等。因此,您可以删除所有意味着更改 DS 和 ES 的指令。

如果“直接将输入与‘1’、‘2’、‘3’的 ASCII 值进行比较”失败,您仍然需要中止程序或重做用户输入。

可以合理地假设您正在使用小型源文件(例如限制为 255 字节)。那么最好在将文件检索到buf后立即关闭该文件。

您想用您的名字替换输入字符的每一次出现。接下来是如何做到这一点:

  • 将源指针寄存器 SI 设置为已保存所选文件内容的 buf 的开头。
  • 将目标指针寄存器 DI 设置为另一个缓冲区的开头,该缓冲区最终将存储在磁盘上新创建的文件中。
  • 启动一个循环,运行您从磁盘读取的字节数。成功读取操作后,DOS 会在 AX 中提供该编号。
  • 对于不是替换候选的每个字符,您只需存储未修改的字符,但每次遇到替换候选时,您都会存储组成您名字的字符。
Top:
    mov  al, [si]     ; Read from 'buf' \ LODSB
    inc  si                             /
    mov  [di], al     ; Write to 'anotherbuf' \ STOSB
    inc  di                                   / 
    cmp  al, dl       ; DL is the replace candidate
    jne  .b           ; Nothing special, so continue the loop

    dec  di           ; Take back the last char written and ...
    mov  bx, offset replacement ; ... substitute by ASCIIZ string
    mov  al, [bx]     ; There would better be at least 1 true char
.a: inc  bx
    mov  [di], al     ; Write to 'anotherbuf'   \ STOSB
    inc  di                                     /
    mov  al, [bx]
    cmp  al, 0        ; For all chars except zero
    jne  .a

.b: dec  cx           ; For all chars in 'buf' \ LOOP TOP
    jnz  Top                                   /

现在是创建新文件并将“anotherbuf”的内容写入其中的时候了。

; Calculate the length of the modified buffer
mov cx, si ; SI points to the end of the modified part

获取新内容的大小不是通过复制“修改部分末尾的地址”,而是通过计算结束地址和起始地址之间的差

mov  cx, di
sub  cx, anotherbuf

或更短,通过 LEA:

lea  cx, [di - anotherbuf]
© www.soinside.com 2019 - 2024. All rights reserved.