问题
I have recently started learning x8086 instructions and knowledge on instructions is rather poor. I am trying to change the current working directory using dos function 3Bh and then create a folder named "test2" on the directory using 39h. Can't understand what the problem is or is it a emu8086 issue.
.MODEL SMALL,C
.STACK
.DATA
CD db "c:\test1",0
dir db "test2",0
.CODE
mov ax,@data
mov ds,ax;
mov dx,offset CD
mov ah,3Bh
int 21h
mov dx, offset dir
mov ah, 39h
int 21h
mov ah,4ch
int 21h
回答1:
It's an emu8086 issue:
1) The C: drive is virtual and mapped to \emu8086\vdrive\C. The only way I found to access the real C: is a junction.
2) int 21h / AH=39h
(MKDIR) needs a full path.
Following example works on the virtual drive and a junction:
.MODEL SMALL
.STACK
.DATA
CD db "c:\test1\",0
dir db "c:\test1\test2",0
buf db 64 DUP ('$')
errchdir db "ERROR CHDIR $"
errmkdir db "ERROR MKDIR $"
temp dw ?
.CODE
mov ax,@data
mov ds,ax
call show_drive
call show_cwd
mov dx,offset CD ; DS:DX -> ASCIZ pathname to become current directory (max 64 bytes)
mov ah,3Bh ; CHDIR - SET CURRENT DIRECTORY
int 21h
jc err_chdir
call show_drive
call show_cwd
mov dx, offset dir ; DS:DX -> ASCIZ pathname
mov ah, 39h ; MKDIR - CREATE SUBDIRECTORY
int 21h
jc err_mkdir
mov dx,offset dir ; DS:DX -> ASCIZ pathname to become current directory
mov ah,3Bh ; CHDIR - SET CURRENT DIRECTORY
int 21h
jc err_chdir
call show_cwd
mov ax,4c00h
int 21h
err_chdir:
mov [temp], ax
mov dx, OFFSET errchdir
mov ah, 09h
int 21h
mov ax, [temp]
mov dl, al
or dl, 30h
mov ah, 02
int 21h
mov ax,4c01h
int 21h
err_mkdir:
mov [temp], ax
mov dx, OFFSET errmkdir
mov ah, 09h
int 21h
mov ax, [temp]
mov dl, al
or dl, 30h
mov ah, 02
int 21h
mov ax,4c02h
int 21h
show_drive:
mov ah, 19h ; GET CURRENT DEFAULT DRIVE
int 21h
mov dl, al
add dl, 41h
mov ah, 02h
int 21h
mov dl, ':'
int 21h
call crlf
ret
show_cwd:
mov si, OFFSET buf
xor dl, dl ; Actual drive
mov ah, 47h ; CWD - GET CURRENT DIRECTORY
int 21h
mov si, OFFSET buf ; Print buf until '\0'
L1:
lodsb
test al, al
jz L2
mov dl, al
mov ah, 02h
int 21h
jmp L1
L2:
call crlf
ret
crlf:
mov ah, 02h
mov dl, 13
int 21h
mov dl, 10
int 21h
ret
Addendum
The system of "current directory" in emu8086 is a buggy mess. I suggest to use only full paths w/o drive. First the current directory have to be switched from c.\...\emu8086\MyBuild\
to C:\...\emu8086\vdrive\
.
Construct two directories: C:\...\emu8086\vdrive\C\TEST1
and C:\...\emu8086\vdrive\C\TEST1\TEST2
(subdirectory of TEST1) and "enjoy" following example:
.MODEL SMALL
.STACK
.DATA
ROOT db "..\",0
test1 db "\TEST1\TEST1.TXT", 0
test2 db "\TEST1\TEST2\TEST2.TXT", 0
test3 db "\TEST1\TEST3.TXT", 0
DIR1 db "\TEST1\",0
DIR2 db "\TEST1\TEST2\",0
dta db 128 DUP(?)
temp dw ?
errcreate db "ERROR CREATE $"
.CODE
main PROC
mov ax, @data
mov ds, ax
; break out of "MyBuild" = switch current directory to "\vdrive\C\"
mov ah, 3Bh ; CHDIR - SET CURRENT DIRECTORY
mov dx, OFFSET ROOT ; DS:DX -> ASCIZ pathname to become current directory (max 64 bytes)
int 21h ; Call MS-DOS
; create test1.txt
mov ah, 3Ch ; CREAT - CREATE OR TRUNCATE FILE
mov dx, OFFSET test1 ; DS:DX -> ASCIZ filename
xor cx, cx ; File attributes
int 21h ; Call MS-DOS
jc err_create
mov ah, 3Eh ; CLOSE - CLOSE FILE
mov bx, ax ; File handle
int 21h ; Call MS-DOS
; create test2.txt
mov ah, 3Ch ; CREAT - CREATE OR TRUNCATE FILE
mov dx, OFFSET test2 ; DS:DX -> ASCIZ filename
xor cx, cx ; File attributes
int 21h ; Call MS-DOS
jc err_create
mov ah, 3Eh ; CLOSE - CLOSE FILE
mov bx, ax ; File handle
int 21h ; Call MS-DOS
; create test3.txt
mov ah, 3Ch ; CREAT - CREATE OR TRUNCATE FILE
mov dx, OFFSET test3 ; DS:DX -> ASCIZ filename
xor cx, cx ; File attributes
int 21h ; Call MS-DOS
jc err_create
mov ah, 3Eh ; CLOSE - CLOSE FILE
mov bx, ax ; File handle
int 21h ; Call MS-DOS
; show first directory (C:\...\emu8086\vdrive\C\TEST1)
mov si, OFFSET DIR1
call show_dir
call crlf
; show second directory (C:\...\emu8086\vdrive\C\TEST1\TEST2)
mov si, OFFSET DIR2
call show_dir
mov ax,4c00h ; return 0
int 21h ; Call MS-DOS
main ENDP
err_create PROC
mov [temp], ax ; Error code
mov ah, 09h ; WRITE STRING TO STANDARD OUTPUT
mov dx, OFFSET errcreate ; DS:DX -> '$'-terminated string
int 21h ; Call MS-DOS
mov ax, [temp] ; Error code
or al, 30h ; Convert to ASCII
mov ah, 02 ; WRITE CHARACTER TO STANDARD OUTPUT
mov dl, al ; character to write
int 21h ; Call MS-DOS
mov ax,4c01h ; return 1
int 21h ; Call MS-DOS
err_create ENDP
show_asciz PROC
L1:
lodsb
test al, al ; End of string?
jz L2 ; Yes: end of loop
mov ah, 02h ; WRITE CHARACTER TO STANDARD OUTPUT
mov dl, al ; character to write
int 21h ; Call MS-DOS
jmp L1 ; loop
L2:
ret
show_asciz ENDP
show_dir PROC ; DS:SI pointer to full path
; findfirst
mov ah, 1AH ; SET DISK TRANSFER AREA ADDRESS
mov dx, OFFSET dta ; dta: disk transfer area
int 21h ; Call MS-DOS
mov ah, 4Eh ; FINDFIRST - FIND FIRST MATCHING FILE
mov dx, si ; DS:DX -> ASCIZ file specification (may include path and wildcards)
xor cx, cx ; File attribute mask
int 21h ; Call MS-DOS
jc Finish
mov si, OFFSET dta + 1Eh ; DS:SI pointer to found entry
call show_asciz
call crlf
; findnext
findnext:
mov ah, 4FH ; FIND NEXT MATCHING FILE
int 21h ; Call MS-DOS
jc Finish
mov si, OFFSET dta + 1Eh ; DS:SI pointer to found entry
call show_asciz
call crlf
jmp findnext
Finish:
ret
show_dir ENDP
crlf PROC
mov ah, 02h ; WRITE CHARACTER TO STANDARD OUTPUT
mov dl, 13 ; Carriage return (CR)
int 21h ; Call MS-DOS
mov dl, 10 ; Line feed (LF)
int 21h ; Call MS-DOS
ret
crlf ENDP
来源:https://stackoverflow.com/questions/27308980/dos-instruction-3bh-on-emu8086-changing-working-directory