Dos instruction 3Bh on emu8086 changing working directory

谁都会走 提交于 2019-12-20 05:46:20

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!