assembly 使用TASM写入文件

twh00eeo  于 2023-04-06  发布在  其他
关注(0)|答案(1)|浏览(176)

在大学里,我被分配了以下任务:
将两个文本文件的内容逐个字符地进行比较。只将第一个文件中的字符及其在文件中的位置号与第二个文件中的相应字符不匹配的字符写入新的文本文件。使用TASM汇编程序。
好吧,我写了程序,用Turbo汇编器运行,但没有任何东西被写入output.txt文件。所有文件都在同一个目录下。
file1.txt的内容是abobabiba1,file2.txt的内容是abobapipa1
从理论上讲,应该将这样的内容写入文件:

5 7

bb
.model large
.stack 1000h
.data
    infile1 db "file1.txt", 0
    infile2 db "file2.txt", 0
    outfile db "output.txt", 0
    buffer1 db 1000h dup(?)
    buffer2 db 1000h dup(?)
    outfile_char db 0
    position db 0
    end_of_file db 0
.code
main proc
    ; open the first input file
    mov ah, 3dh
    mov al, 0
    lea dx, infile1
    int 21h
    mov bx, ax ; bx contains the first file descriptor

    ; open second input file
    mov ah, 3dh
    mov al, 0
    lea dx, infile2
    int 21h
    mov cx, ax ; cx contains the second file descriptor

    ; create output file
    mov ah, 3ch
    mov al, 0
    lea dx, outfile
    int 21h
    mov dx, ax ; dx contains the output file descriptor

    ; read the contents of the first file into buffer1
    mov ah, 3fh
    mov bx, ax
    lea dx, buffer1
    mov cx, 1000h
    int 21h
    ; read the contents of the first file into buffer2
    mov ah, 3fh
    mov bx, cx
    lea dx, buffer2
    mov cx, 1000h
    int 21h

    ; compare the contents of the buffers character by character
    mov si, offset buffer1
    mov di, offset buffer2
    mov cx, 1000h
    mov position, 0
    
loop_start:
    mov al, [si]
    mov bl, [di]
    cmp al, bl
    je skip

    ; set the file pointer to the beginning of the file
    mov ah, 42h
    mov al, 0
    mov bx, dx
    int 21h

    ; write information to the output file
    mov ah, 02h
    mov dl, al
    mov ah, 40h
    mov bx, dx
    mov cx, 1
    mov dx, offset outfile_char
    int 21h
    mov ah, 02h
    mov dl, position
    add dl, '0'
    mov ah, 40h
    mov bx, dx
    mov cx, 1
    mov dx, offset outfile_char
    int 21h
    mov ah, 40h
    mov bx, dx
    mov cx, 1000h
    lea dx, buffer1
    int 21h
    mov ah, 40h
    mov bx, dx
    mov cx, 1000h
    lea dx, buffer2
    int 21h
skip:
    ; increment the position and move on to the next character
    inc si
    inc di
    inc position
    ; check for end of file
    cmp position, 10h
    jne loop_start

    ; close the output file
    mov ah, 3eh
    mov bx,dx
    int 21h

    ; close the second input file
    mov ah, 3eh
    mov bx, cx
    int 21h

    ; close the first input file
    mov ah, 3eh
    mov bx, ax
    int 21h

    ; we complete the program
    mov ah, 4ch
    int 21h

main endp
end main
bf1o4zei

bf1o4zei1#

你确定DS指向了你的.data部分吗?不记得.code是否处理了那个...
你的程序中最重要的错误是,你使用了几个寄存器,每个寄存器都有多种用途,而且你没有采取预防措施,比如在堆栈上保留它们预先存在的值。
另一种方法是将一些数据存储在基于内存的变量中。你绝对应该为你的文件句柄选择这个,就像下面的代码一样:

; open the first input file
    mov ah, 3dh
    mov al, 0
    lea dx, infile1
    int 21h
    jc  SomeError
    mov handle1, ax   ; the first file descriptor

    ; open second input file
    mov ah, 3dh
    mov al, 0
    lea dx, infile2
    int 21h
    jc  SomeError
    mov handle2, ax   ; the second file descriptor

    ; create output file
    mov ah, 3ch
    mov al, 0         <<<< THIS IS AN ERROR: NEEDS TO BE CX=0
    lea dx, outfile
    int 21h
    jc  SomeError
    mov handle3, ax   ; the output file descriptor

    ; read the contents of the first file into buffer1
    mov ah, 3fh
    mov bx, handle1
    mov cx, 16
    lea dx, buffer1
    int 21h
    jc  SomeError

    ; read the contents of the first file into buffer2
    mov ah, 3fh
    mov bx, handle2
    mov cx, 16
    lea dx, buffer2
    int 21h
    jc  SomeError

    ...

    ; close the output file
    mov ah, 3eh
    mov bx, handle3
    int 21h

    ; close the second input file
    mov ah, 3eh
    mov bx, handle2
    int 21h

    ; close the first input file
    mov ah, 3eh
    mov bx, handle1
    int 21h
; set the file pointer to the beginning of the file
mov ah, 42h
mov al, 0
mov bx, dx
int 21h

在程序的中间部分,你比较缓冲区,你也在尝试重置输出文件指针。我说“尝试”是因为你没有正确设置参数!但是为什么你需要重置任何东西呢?就在一个文件创建之后,文件指针已经在开始处了。此外,每次查找都重置文件指针会覆盖以前的结果!

mov ah, 02h
mov dl, al
...
mov ah, 02h
mov dl, position
add dl, '0'

在“将信息写入输出文件”这一部分中,您将字符输出到屏幕(但不完整)与缓冲区输出到文件混合在一起。如果输出到屏幕的字符是出于测试目的,则在文本中使用适当的注解记录此内容,否则删除这些行,因为它们非常令人不安。
这就是输出字符的方式。请注意,该字符位于地址SI:

; write information to the output file
mov ah, 40h
mov bx, handle3
mov cx, 1
mov dx, si
int 21h
jc  SomeError

在这里你可以学习如何写位置:

mov al, position       ; [0,9] will work fine for your input files
add al, '0'
mov outfile_char, al
mov ah, 40h
mov bx, handle3
mov cx, 1
mov dx, offset outfile_char
int 21h
jc  SomeError

在处理输入文件'abobabiba 1'和'abobapipa 1'时,我希望得到一个4字节的输出文件'b5 b7'。

相关问题