2016-04-25 18 views
0

我想在控制台中输入文件的名称时创建一个文件,我该怎么做?我已经试过这两个程序:如何从用户输入[asm,dos]写入文件?

filenameStr db 13,0,13 dup("$") 
createline db 10,13,"/c/ ","$" 
space db " ","$" 
filehandle dw 0 

PROC:

proc Createfile 
mov dx,offset createline 
mov ah,9h 
int 21h 
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 
xor bx,bx 
call WipeClean 

call CreateFile1 
call CloseFile 
call GetCommandLetter 
endp CreateFile 

和:

proc CreateFile1 
    mov ah,3ch 
    mov cx,00000000b 
    lea dx,[filenameStr] 
    int 21h 
    mov [filehandle],ax 
    ret 
endp CreateFile1 

注:这些程序没有在代码显示,因为我已经没有写入文件过程,将代码更改为旧代码。

完整的程序是在这里:

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 
filereaderline db "file's text:","$" 


CODESEG  
proc WipeClean 
    mov [byte ptr fileString + bx], 0 
    inc bx 
    cmp bx, 255 
    jb WipeClean 
endp WipeClean 

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 ah,0 
    mov al,2 
    int 10h 

    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,'h' 
    je _help 

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

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

    cmp bl,'/' 
    jne _Error 
    cmp bh,'e' 
    je _exit 

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


    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 

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

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 
    xor bx,bx 
    call WipeClean 
    call ReadFile 
    mov dx,offset filereaderline 
    mov ah,9h 
    int 21h 
    call DisplayFileString 
    call CloseFile 
    jmp GetCommandLetter 





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

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

此代码是很难遵循。你是否理解使用'call'和使用'jmp/je/jne'的区别?当它遇到例程的结尾时,你认为在例程(比如_Error)中会发生什么? –

+0

我已经更改了代码,请注意我在问题中显示的过程不再存在,因为它是旧代码。希望你现在可以关注它 – Warrior0201

+0

那么,你运行它会发生什么?我假设'/ h'按预期工作。但是当你做'/ r'时会发生什么?我猜它会提示你输入名称并让你输入。它看起来应该打印出刚输入的名称。那样有用吗?你到底在用什么名字?你认为这行代码是'mov [byte ptr filenameStr + 2 + 8],0'?具体来说,'8'是什么意思? OpenFile打印错误?这将我们带到了WipeClean。你用'call'调用它,并且在处理所有255个字节之后,在proc结尾会发生什么? –

回答

1

读DOS API,您会看到的CreateFile的OpenFile是非常类似的功能。在您的程序中,您已成功打开,但创建失败,因为您在用户@SepRoland帮助您时遇到了与以前相同的错误。你忘了实际的文件名从开始偏移2在你给DOS的结构中。

proc CreateFile1 
    mov ah,3ch 
    mov cx,00000000b 
    lea dx,[filenameStr +2]    <= Add the 2 here! 
    int 21h 
    jc ThisIsAnErrorOnCreatingAFile <= Do something with the carry flag! 
    mov [filehandle],ax 
    ret 
endp CreateFile1