更改工作目录的emu8086上的Dos指令3Bh

时间:2014-12-05 04:48:48

标签: assembly x86 dos

我最近开始学习x8086指令并且指令知识相当差。我正在尝试使用dos函数3Bh更改当前工作目录,然后使用39h在目录上创建名为“test2”的文件夹。无法理解问题是什么,或者是emu8086问题。

      .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 个答案:

答案 0 :(得分:0)

这是一个emu8086问题:

1)C:驱动器是虚拟的,并映射到\ emu8086 \ vdrive \ C.我发现访问真实C的唯一方法是junction

2)int 21h / AH=39h(MKDIR)需要一条完整的路径。

以下示例适用于虚拟驱动器和联结:

.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

<强>附录

&#34;当前目录&#34;的系统在emu8086中是一个混乱的车。我建议只使用没有驱动器的完整路径。首先,当前目录必须从c.\...\emu8086\MyBuild\切换到C:\...\emu8086\vdrive\ 构建两个目录:C:\...\emu8086\vdrive\C\TEST1C:\...\emu8086\vdrive\C\TEST1\TEST2(TEST1的子目录)和&#34;享受&#34;以下示例:

.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