汇编 x86 NULL 终止符 (TASM)
Assembly x86 NULL terminator (TASM)
此程序必须简单地从文件中读取文本并将其输出。问题是文件名是由用户输入的。
到目前为止我做了什么:
- 我放置了一个零终止符来表示字符串的结尾
- 并在 .exe 文件所在的确切文件夹中创建了一个新的文本文件
我得到的是:
无法打开文件
.model small
.stack 100h
.data
filename db 255 dup(0)
line db 255 dup(0)
filehandle dw ?
line_len dw ?
.code
newline macro ;NEW LINE
;
mov dl, 10 ;
mov ah, 02h ;
;
int 21h ;
;
mov dl, 13 ;
mov ah, 02h ;
;
int 21h ;
endm ;NEW LINE
main:
mov ax, @data
mov ds, ax
lea si, filename
mov ah, 01h
char_input:
int 21h
cmp al, 0dh
je zero_terminator
mov [si], al
inc si
jmp char_input
zero_terminator:
mov [si], '[=10=]'
int 21h
open_file:
lea dx, filename
mov al, 0
mov ah, 3Dh
int 21h
mov filehandle, ax
int 21h
read_line:
mov ah, 3Fh
lea bx, filehandle
mov cx, 1
int 21h
cmp ax, 0 ;EOF
je EO_file
inc line_len
jmp read_line:
EO_file:
newline ;macro
lea dx, line ;print line
mov bx, 1
mov ah, 40h
mov cx, line_len
int 21h
mov ah, 4ch
int 21h
end main
总结 Jester 的评论并添加一些评论,这是您的程序存在的问题:
zero_terminator:
mov [si], '[=10=]'
int 21h
应删除此 int 21h
指令。使用 '\0' 不会以零终止文件名。最好使用普通的 0.
mov filehandle, ax
int 21h
read_line:
此 int 21h
指令也应删除。
read_line:
mov ah, 3Fh
lea bx, filehandle
mov cx, 1
int 21h
在这个读取块中,您忘记了在 DX 中设置缓冲区地址,并且错误地将文件句柄变量的地址移到了 BX 中,而实际上您需要它的值。 另请注意,缓冲区地址需要随着此循环的每次迭代而递增!更改为:
lea dx, line
read_line:
mov ah, 3Fh
mov bx, filehandle
mov cx, 1
int 21h
;;; jc EO_file ??
cmp ax, 0 ;EOF
je EO_file
inc line_len
inc dx
jmp read_line ; <-- Here you had a typo!
最好在打开文件后检查 CF 以确认您确实获得了有效句柄。
此程序必须简单地从文件中读取文本并将其输出。问题是文件名是由用户输入的。
到目前为止我做了什么:
- 我放置了一个零终止符来表示字符串的结尾
- 并在 .exe 文件所在的确切文件夹中创建了一个新的文本文件
我得到的是:
无法打开文件
.model small .stack 100h .data filename db 255 dup(0) line db 255 dup(0) filehandle dw ? line_len dw ? .code newline macro ;NEW LINE ; mov dl, 10 ; mov ah, 02h ; ; int 21h ; ; mov dl, 13 ; mov ah, 02h ; ; int 21h ; endm ;NEW LINE main: mov ax, @data mov ds, ax lea si, filename mov ah, 01h char_input: int 21h cmp al, 0dh je zero_terminator mov [si], al inc si jmp char_input zero_terminator: mov [si], '[=10=]' int 21h open_file: lea dx, filename mov al, 0 mov ah, 3Dh int 21h mov filehandle, ax int 21h read_line: mov ah, 3Fh lea bx, filehandle mov cx, 1 int 21h cmp ax, 0 ;EOF je EO_file inc line_len jmp read_line: EO_file: newline ;macro lea dx, line ;print line mov bx, 1 mov ah, 40h mov cx, line_len int 21h mov ah, 4ch int 21h end main
总结 Jester 的评论并添加一些评论,这是您的程序存在的问题:
zero_terminator:
mov [si], '[=10=]'
int 21h
应删除此 int 21h
指令。使用 '\0' 不会以零终止文件名。最好使用普通的 0.
mov filehandle, ax
int 21h
read_line:
此 int 21h
指令也应删除。
read_line:
mov ah, 3Fh
lea bx, filehandle
mov cx, 1
int 21h
在这个读取块中,您忘记了在 DX 中设置缓冲区地址,并且错误地将文件句柄变量的地址移到了 BX 中,而实际上您需要它的值。 另请注意,缓冲区地址需要随着此循环的每次迭代而递增!更改为:
lea dx, line
read_line:
mov ah, 3Fh
mov bx, filehandle
mov cx, 1
int 21h
;;; jc EO_file ??
cmp ax, 0 ;EOF
je EO_file
inc line_len
inc dx
jmp read_line ; <-- Here you had a typo!
最好在打开文件后检查 CF 以确认您确实获得了有效句柄。