在DOSBox与TASM环境下,如何从.asm文件调用外部程序?
Hey there! Let's walk through exactly how to make this work—since you're dealing with DOS-style assembly (using int 21h) and want to run that Python-to-EXE program, then jump back to your .asm code like a regular procedure call.
First: Make Sure Your Python Script is a Valid DOS EXE
Before diving into assembly, double-check you converted your Python script correctly:
- Use a tool like
pyinstallerwith the--onefileflag to create a single EXE:pyinstaller --onefile your_script.py - Copy the generated EXE (from the
distfolder) into the same directory as your .asm file. - Critical: Make sure you build a console-based EXE (not a windowed one)—DOS/DOSBox needs this to run it properly.
Understanding int 21h/ah=4Bh
The int 21h interrupt with ah=4Bh is DOS's "Execute Program" function. We'll use subfunction 00h (al=00h), which loads and runs the target EXE, then returns control to your assembly program once it's finished—exactly what you want, like calling a procedure.
Required Parameters for ah=4Bh, al=00h
DS:DX: Points to an ASCIIZ string (filename followed by a null byte0) of the EXE you want to run.ES:BX: Points to a parameter block (even if you don't need command-line arguments, some DOS versions require this to exist).AH=4Bh,AL=00h: Tells DOS which function/subfunction to use.
Example Assembly Code (MASM Style)
Here's a complete, commented example that launches your EXE and returns when it's done:
.MODEL SMALL .STACK 100h .DATA ; ASCIIZ filename of your converted Python EXE (ends with 0) TARGET_EXE DB "your_script.exe", 0 ; Parameter block (required for DOS execute function) PARAM_BLOCK DW 0 ; 0 = inherit parent process environment DW OFFSET CMD_ARGS ; Offset of command-line arguments DW 0 ; Segment of command-line args (same as DS, so 0) CMD_ARGS DB 0 ; Empty command line (ends with 0) ; Error message for debugging ERROR_TEXT DB "Failed to launch EXE!$" .CODE MAIN PROC ; Set up data segment MOV AX, @DATA MOV DS, AX MOV ES, AX ; Align ES with DS for easier parameter block access ; Prepare to call DOS execute function MOV AH, 4Bh MOV AL, 00h ; Subfunction 00h = load & execute, return when done LEA DX, TARGET_EXE ; DS:DX points to the EXE filename LEA BX, PARAM_BLOCK ; ES:BX points to the parameter block INT 21h ; Trigger DOS interrupt to run the EXE ; Check if the execute call succeeded JC EXEC_ERROR ; If carry flag (CF) is set, an error occurred ; ------------------------------ ; This code runs AFTER the EXE finishes ; Add your post-execution logic here ; ------------------------------ ; Exit the assembly program cleanly JMP EXIT_PROGRAM EXEC_ERROR: ; Print error message (AH contains DOS error code if you need it) MOV AH, 09h LEA DX, ERROR_TEXT INT 21h EXIT_PROGRAM: ; DOS exit function MOV AH, 4Ch INT 21h MAIN ENDP END MAIN
Key Notes on the Code
- ASCIIZ Filename: The
TARGET_EXEstring must end with a0—DOS uses this to know where the filename stops. - Parameter Block: Even with empty arguments, we provide a minimal block. If you want to pass command-line args to your Python EXE, modify
CMD_ARGSto something likeDB "hello world", 0(space-separated, ends with0). - Error Handling: The carry flag (CF) is set if DOS can't launch the EXE (e.g., file not found). You can check
AHfor the specific error code (look up DOS error codes for details). - Return Behavior: Once the Python EXE exits, control jumps back to the line right after
INT 21hin your assembly code—just like a procedure call.
Important Gotchas
- This is for 16-bit DOS assembly. You'll need to run your compiled .exe in DOSBox or a real DOS environment (modern Windows doesn't natively support 16-bit DOS programs).
- Make sure your Python EXE is compatible with DOS/DOSBox—avoid using Python features that rely on modern OS APIs.
- Double-check filenames: DOS is case-insensitive, but mismatched names (e.g.,
YourScript.exevsyour_script.exe) will cause errors.
内容的提问来源于stack exchange,提问作者Fro-Yo

