INT 21h AH=39h creates one directory, what MD (MKDIR) does at the prompt. The name at DS:DX ends with a 0 byte, not with "$": all the DOS services that take a path use ASCIIZ strings, and only the console's 09h uses "$". The path can be relative to the current directory (TESTDIR, SUB\NEW) or absolute (\TOOLS\NEW, C:\TOOLS\NEW), up to 64 characters, and each part is an 8.3 name.

Only the last part of the path is created. Every directory before it must exist, or the call fails with error 3.

AX (CF = 1)Why
3path not found: a directory on the way does not exist, or the name is not valid
5access denied: a file or directory of that name exists, the parent directory is full, or the disk is write-protected

A FAT disk's root directory has a fixed number of entries (112 on a 360 KB floppy, 512 on a hard disk), so making one more directory there fails with 5 even when the disk has room. Subdirectories grow as needed. The example makes TESTDIR, tries again, and removes it:

prints: mkdir TESTDIR: ok / mkdir TESTDIR again: error 5 / rmdir TESTDIR: ok
MOV DX, OFFSET MKM1
MOV AH, 09h
INT 21h
MOV AH, 39h ; DOS: make the directory named at DS:DX
MOV DX, OFFSET DIR1
INT 21h
CALL RESULT ; ok
MOV DX, OFFSET AGAINM1
MOV AH, 09h
INT 21h
MOV AH, 39h
MOV DX, OFFSET DIR1
INT 21h
CALL RESULT ; error 5: it exists now
MOV DX, OFFSET RMM1
MOV AH, 09h
INT 21h
MOV AH, 3Ah ; DOS: remove it again
MOV DX, OFFSET DIR1
INT 21h
CALL RESULT
DIR1 DB "TESTDIR", 0
MKM1 DB "mkdir TESTDIR: $"
AGAINM1 DB "mkdir TESTDIR again: $"
RMM1 DB "rmdir TESTDIR: $"
RESULT PROC NEAR ; print "ok", or "error" and AX when CF = 1
PUSHF ; keeps AX and CF for the caller
PUSH AX
MOV DX, OFFSET OKMSG
JNC RESULT1
MOV DX, OFFSET ERRMSG
MOV AH, 09h
INT 21h
POP AX
PUSH AX
CALL PDEC ; the error code
MOV DX, OFFSET CRLF
RESULT1:
MOV AH, 09h
INT 21h
POP AX
POPF
RET
RESULT ENDP
OKMSG DB "ok", 13, 10, "$"
ERRMSG DB "error $"
PDEC PROC NEAR ; print AX in decimal (changes AX BX CX DX)
MOV BX, 10
XOR CX, CX ; digits on the stack
PDEC1:
XOR DX, DX
DIV BX ; AX = AX / 10, DX = the last digit
PUSH DX
INC CX
OR AX, AX
JNZ PDEC1
PDEC2:
POP DX ; the digits come back first to last
ADD DL, "0"
MOV AH, 02h
INT 21h
LOOP PDEC2
RET
PDEC ENDP
CRLF DB 13, 10, "$"

Making a whole path

To create several levels, make each in turn and treat error 5 on the way as "already there":

MOV AH, 39h
MOV DX, OFFSET LEVEL1 ; "OUT", 0
INT 21h ; error 5 is fine: it exists
MOV AH, 39h
MOV DX, OFFSET LEVEL2 ; "OUT\LOGS", 0
INT 21h

In DOSBox-X a drive mounted from a host folder gets a real folder on the host. The name is stored as DOS gives it, in capitals; with long file names enabled, function 7139h of INT 21h makes directories with long names.