我如何从dos asm中的用户输入中获取文件名

how can i get filename from user input in dos asm

我正在制作一个控制台程序,我的文件程序需要文件名,不过,我想从用户输入中获取文件名,所以当你在控制台/r 中写入时,你最多可以写入 15 个字母,包含文件名中的 .txt,但我的代码似乎无法正常工作,我如何才能将用户输入的文件名转换为字符串或此变量 filename db "filename.txt",0?

我的Openfile过程(举例):

proc OpenFile
;Open file
    mov ah,3Dh
    xor al,al
    lea dx,[filename]
    int 21h
    jc openerror
    mov [filehandle],ax
    ret
openerror:  
    mov dx,offset ErrorOpenMsg
    mov ah,9h
    int 21h
    ret
endp OpenFile

原始完整代码:

IDEAL
MODEL small
STACK 100h
DATASEG

szMsg1 db "Hi! What do you want to do?",10,13,10,13,"/h-help(see all the commands)",10,13,"/e-Exit",10,13,10,13,"$"
szHelloWorld db 10,13,"Hello World!",10,13,"$"
ErrorMsg db 10,13,"Illegal Command,Try again!",10,13,"$"
filenameStr db 15 dup(?),0
help db 10,13,"HELP LIST:",10,13,"-----------",10,13,"Commands are:",10,13," /e-Exit",10,13," /h-help",10,13," /1-Says: 'Hello World!'",10,13,"$"
filename db ?,0
filehandle dw 0
ErrorOpenMsg db 'Error',10,13,'$'
FileNameLength db "file name consists of 8 letters max! (dont forget to add '.txt' at the end of the name: 'example.txt')",10,13,"/r/ ","$"
fileString db 255 dup (0)
space db " ","$"
CommandMsg db 10,13,"Enter your command:",10,13,"Command: ","$",10,13
string db ?

CODESEG                                    
proc OpenFile
;Open file
    mov ah,3Dh
    xor al,al
    lea dx,[filenameStr]
    int 21h
    jc openerror
    mov [filehandle],ax
    ret
openerror:  
    mov dx,offset ErrorOpenMsg
    mov ah,9h
    int 21h
    ret
endp OpenFile   

proc ReadFile
    mov ah,3fh
    mov bx,[filehandle]
    mov cx,255
    lea dx,[string]
    int 21h
    ret
endp ReadFile   

proc DeleteFile
    mov ah,41h
    lea dx,[filename]
    int 21h
endp DeleteFile

proc DisplayFileString
    mov ah,09h
    lea dx,[fileString]
    int 21h 
endp DisplayFileString  

proc KeyStroke
    xor ax,ax
    int 16h
endp KeyStroke

proc WriteToFile
    mov ah,40h
    mov bx,[filehandle]
    mov cx,255
    lea dx,[fileString]
    int 21h
    ret
endp WriteToFile

proc CloseFile
    mov ah,3Eh
    mov bx,[filehandle]
    int 21h
    ret
endp CloseFile  

start:
    mov ax, @data
    mov ds, ax

    mov dx,offset szMsg1
    mov ah,9h
    int 21h
    jmp GetCommandLetter

_Error:

    mov dx,offset ErrorMsg
    mov ah,9h
    int 21h 

GetCommandLetter:
    mov dx,offset CommandMsg
    mov ah,9h
    int 21h

    mov ah, 1h
    int 21h
    mov bl,al   

    mov ah, 1h
    int 21h
    mov bh,al   
compare:    
    cmp bl,'/'
    jne _Error
    cmp bh,'e'
    je _exit

    cmp bl,'/'
    jne _Error
    cmp bh,'E'
    je exit

    cmp bl,'/'
    jne _Error
    cmp bh,'h'
    je _help

    cmp bl,'/'
    jne _Error
    cmp bh,'H'
    je _help

    cmp bl,'/'
    jne _Error
    cmp  bh,'1'
    je PrintLine

    mov dx,offset space
    mov ah,9h
    int 21h
    mov dx,offset FileNameLength
    mov ah,9h
    int 21h

    cmp bl,'/'
    jne _Error
    cmp  bh,'r'
    je GetFileName

    cmp bl,'/'
    jne _Error
    cmp  bh,'R'
    je GetFileName

    jmp _Error
_exit:
    jmp exit    

GetFileName:
    mov dx,offset space
    mov ah,9h
    int 21h

    mov dx,offset filenameStr
    mov bx,dx
    mov [byte ptr bx],15
    mov ah,0Ah
    int 21h
    mov dx,offset filenameStr
    mov ah,9h
    int 21h
    call OpenFile
    call ReadFile
    call CloseFile
    jmp GetCommandLetter



_help:  
    mov dx,offset help
    mov ah,9h
    int 21h
    jmp GetCommandLetter

PrintLine:
    mov dx, offset szHelloWorld
    mov ah, 9h
    int 21h
    jmp GetCommandLetter

exit:
    mov ax, 4c00h
    int 21h
END start



    mov [filehandle],ax
    ret
openerror:  
    mov dx,offset ErrorOpenMsg
    mov ah,9h
    int 21h
    ret
endp OpenFile   

proc ReadFile
    mov ah,3fh
    mov bx,[filehandle]
    mov cx,255
    lea dx,[string]
    int 21h
    ret
endp ReadFile   

proc DeleteFile
    mov ah,41h
    lea dx,[filename]
    int 21h
endp DeleteFile

proc DisplayFileString
    mov ah,09h
    lea dx,[fileString]
    int 21h 
endp DisplayFileString  

proc KeyStroke
    xor ax,ax
    int 16h
endp KeyStroke

proc WriteToFile
    mov ah,40h
    mov bx,[filehandle]
    mov cx,255
    lea dx,[fileString]
    int 21h
    ret
endp WriteToFile

proc CloseFile
    mov ah,3Eh
    mov bx,[filehandle]
    int 21h
    ret
endp CloseFile  

start:
    mov ax, @data
    mov ds, ax

    mov dx,offset szMsg1
    mov ah,9h
    int 21h
    jmp GetCommandLetter

_Error:

    mov dx,offset ErrorMsg
    mov ah,9h
    int 21h 

GetCommandLetter:
    mov dx,offset CommandMsg
    mov ah,9h
    int 21h

    mov ah, 1h
    int 21h
    mov bl,al   

    mov ah, 1h
    int 21h
    mov bh,al   
compare:    
    cmp bl,'/'
    jne _Error
    cmp bh,'e'
    je _exit

    cmp bl,'/'
    jne _Error
    cmp bh,'E'
    je exit

    cmp bl,'/'
    jne _Error
    cmp bh,'h'
    je _help

    cmp bl,'/'
    jne _Error
    cmp bh,'H'
    je _help

    cmp bl,'/'
    jne _Error
    cmp  bh,'1'
    je PrintLine

    mov dx,offset space
    mov ah,9h
    int 21h
    mov dx,offset FileNameLength
    mov ah,9h
    int 21h

    cmp bl,'/'
    jne _Error
    cmp  bh,'r'
    je GetFileName

    cmp bl,'/'
    jne _Error
    cmp  bh,'R'
    je GetFileName

    jmp _Error
_exit:
    jmp exit    

GetFileName:
    mov dx,offset space
    mov ah,9h
    int 21h

    mov dx,offset filenameStr ;setting letters into string from input
    mov bx,dx
    mov [byte ptr bx],15
    mov ah,0Ah
    int 21h
    mov dx,offset filenameStr ;output of the string,string input supposidly bad
    mov ah,9h
    int 21h
    call OpenFile
    call ReadFile
    call CloseFile
    jmp GetCommandLetter



_help:  
    mov dx,offset help
    mov ah,9h
    int 21h
    jmp GetCommandLetter

PrintLine:
    mov dx, offset szHelloWorld
    mov ah, 9h
    int 21h
    jmp GetCommandLetter

exit:
    mov ax, 4c00h
    int 21h
END start

新-完整代码:

IDEAL
MODEL small
STACK 100h
DATASEG

szMsg1 db "Hi! What do you want to do?",10,13,10,13,"/h-help(see all the commands)",10,13,"/e-Exit",10,13,10,13,"$"
szHelloWorld db 10,13,"Hello World!",10,13,"$"
ErrorMsg db 10,13,"Illegal Command,Try again!",10,13,"$"
filenameStr db 13,0,13 dup("$")
help db 10,13,"HELP LIST:",10,13,"-----------",10,13,"Commands are:",10,13," /e-Exit",10,13," /h-help",10,13," /1-Says: 'Hello World!'",10,13,"$"
filename db ?,0
filehandle dw 0
ErrorOpenMsg db 'Error',10,13,'$'
FileNameLength db "file name consists of 8 letters max! (dont forget to add '.txt' at the end of the name: 'example.txt')",10,13,"/r/ ","$"
fileString db 255 dup (0)
space db " ","$"
CommandMsg db 10,13,"Enter your command:",10,13,"Command: ","$",10,13
string db ?

CODESEG                                    
proc OpenFile
;Open file
    mov ah,3Dh
    xor al,al
    lea dx,[filenameStr+2]
    int 21h
    jc openerror
    mov [filehandle],ax
    ret
openerror:  
    mov dx,offset ErrorOpenMsg
    mov ah,9h
    int 21h
    ret
endp OpenFile   

proc ReadFile
    mov ah,3fh
    mov bx,[filehandle]
    mov cx,255
    lea dx,[fileString]
    int 21h
    ret
endp ReadFile   

proc DeleteFile
    mov ah,41h
    lea dx,[filenameStr+2]
    int 21h
endp DeleteFile

proc DisplayFileString
    mov ah,09h
    lea dx,[fileString]
    int 21h 
endp DisplayFileString  

proc KeyStroke
    xor ax,ax
    int 16h
endp KeyStroke

proc WriteToFile
    mov ah,40h
    mov bx,[filehandle]
    mov cx,255
    lea dx,[fileString]
    int 21h
    ret
endp WriteToFile

proc CloseFile
    mov ah,3Eh
    mov bx,[filehandle]
    int 21h
    ret
endp CloseFile  

start:
    mov ax, @data
    mov ds, ax

    mov dx,offset szMsg1
    mov ah,9h
    int 21h
    jmp GetCommandLetter

_Error:

    mov dx,offset ErrorMsg
    mov ah,9h
    int 21h 

GetCommandLetter:
    mov dx,offset CommandMsg
    mov ah,9h
    int 21h

    mov ah, 1h
    int 21h
    mov bl,al   

    mov ah, 1h
    int 21h
    mov bh,al   
compare:    
    cmp bl,'/'
    jne _Error
    cmp bh,'e'
    je _exit

    cmp bl,'/'
    jne _Error
    cmp bh,'E'
    je exit

    cmp bl,'/'
    jne _Error
    cmp bh,'h'
    je _help

    cmp bl,'/'
    jne _Error
    cmp bh,'H'
    je _help

    cmp bl,'/'
    jne _Error
    cmp  bh,'1'
    je PrintLine

    mov dx,offset space
    mov ah,9h
    int 21h
    mov dx,offset FileNameLength
    mov ah,9h
    int 21h

    cmp bl,'/'
    jne _Error
    cmp  bh,'r'
    je GetFileName

    cmp bl,'/'
    jne _Error
    cmp  bh,'R'
    je GetFileName

    jmp _Error
_exit:
    jmp exit    

GetFileName:
    mov dx,offset space 
    mov ah,9h 
    int 21h
    mov dx,offset filenameStr
    mov bx,dx
    mov [byte ptr bx],13    ;8+1+3+1
    mov ah,0Ah
    int 21h
    mov dx,offset filenameStr + 2
    mov ah,9h
    int 21h


    mov byte ptr [filenameStr+2+8],0


    call OpenFile 
    call ReadFile
    call CloseFile 
    jmp GetCommandLetter



_help:  
    mov dx,offset help
    mov ah,9h
    int 21h
    jmp GetCommandLetter

PrintLine:
    mov dx, offset szHelloWorld
    mov ah, 9h
    int 21h
    jmp GetCommandLetter

exit:
    mov ax, 4c00h
    int 21h
END start
filenameStr db 15 dup(?),0
filename db ?,0

您有这两个定义可以解决您的问题。第二个 (filename) 太小而没有任何用处,这就是为什么您的 deleteFile 过程会失败!第一个 (filenameStr) 是 DOS 输入函数的输入结构。这足够大,但你需要将它的第一个字节初始化为小于 15 的值,我建议 13,因为这将允许 8 个字符 + 1 个点 + 3 个字符 + 回车 return.

mov dx,offset filenameStr
mov bx,dx
mov byte ptr [bx],13    ;8+1+3+1
mov ah,0Ah
int 21h

当您想要显示此文本时,您需要使用 $ 美元符号终止它,并注意实际文本在此结构中从偏移量 2 开始。我是这样解决的:

filenameStr db 13,0,13 dup("$")


mov dx,offset filenameStr + 2
mov ah,9h
int 21h

要成功打开文件,您需要先将回车 return 替换为零,然后再次注意文本从偏移量 2 开始。