Skip to main content
Copy edited (e.g. ref. <https://en.wiktionary.org/wiki/cleanup#Noun>). Fixed the question formation - missing auxiliary (or helping) verb - see e.g. <https://www.youtube.com/watch?v=t4yWEt0OSpg&t=1m49s> (see also <https://www.youtube.com/watch?v=kS5NfSzXfrI> (QUASM)) - alternatively, drop the quest
Source Link

How tocan I properly execute and clean up after a DOS MZ executable loaded into memory with int21 function 4b01h?

Ralf Brown's Interrupt List describes a subvariant of the DOS int21/4Bh function with AL=01, where the program is loaded into memory and a PSP + stack are allocated for it, but the program is not executed. The CS:IP and SS:IP are placed in the parameter block structure that was provided as input in ES:BX.

This works, but what do I need to do in order to execute the program and make sure it returns to the point where I called it from (I am doing this from C, FWIW)? I imagine I can't just cast CS:IP to a void (far *func)(void) and call it a day?

#pragma pack(1) struct { uint16 envSegment; uint16 cmdlineOffset; uint16 cmdlineSegment; uint16 fcb1Offset; uint16 fcb1Segment; uint16 fcb2Offset; uint16 fcb2Segment; uint16 sp; uint16 ss; uint16 ip; uint16 cs; } exeLoadParams; static int loadprog(const char* file, const char far* cmdline) { union REGS rin, rout; rin.h.ah = 0x4B; rin.h.al = 0x1; // DS will be data segment of current executable, no need to provide with intdosx()? rin.x.dx = (unsigned int)file;    exeLoadParams.envSegment = 0; exeLoadParams.cmdlineOffset = FP_OFF(cmdline); exeLoadParams.cmdlineSegment = FP_SEG(cmdline); // the two FCBs are located at offsets 0x5c and 0x6c in this program's PSP exeLoadParams.fcb1Offset = 0x5c; exeLoadParams.fcb1Segment = _psp; exeLoadParams.fcb2Offset = 0x6c; exeLoadParams.fcb2Segment = _psp; // ES == DS guaranteed? it seems to work rin.x.bx = (unsigned int)&exeLoadParams; intdos(&rin, &rout); // exeLoadParams now contains CS:IP and SS:SP, but what next? } 

Also, what kind of clean-upcleanup do I need to do once the program returns? I tried freeing the block whose address I calculated as CS - PSP_SIZE and it seems to have freed most of the memory, but not all of it - in this particular case, 9 paragraphs worth of it were "lost".

How to properly execute and clean up after a DOS MZ executable loaded into memory with int21 function 4b01h?

Ralf Brown's Interrupt List describes a subvariant of the DOS int21/4Bh function with AL=01, where the program is loaded into memory and a PSP + stack are allocated for it, but the program is not executed. The CS:IP and SS:IP are placed in the parameter block structure that was provided as input in ES:BX.

This works, but what do I need to do in order to execute the program and make sure it returns to the point where I called it from (I am doing this from C, FWIW)? I imagine I can't just cast CS:IP to a void (far *func)(void) and call it a day?

#pragma pack(1) struct { uint16 envSegment; uint16 cmdlineOffset; uint16 cmdlineSegment; uint16 fcb1Offset; uint16 fcb1Segment; uint16 fcb2Offset; uint16 fcb2Segment; uint16 sp; uint16 ss; uint16 ip; uint16 cs; } exeLoadParams; static int loadprog(const char* file, const char far* cmdline) { union REGS rin, rout; rin.h.ah = 0x4B; rin.h.al = 0x1; // DS will be data segment of current executable, no need to provide with intdosx()? rin.x.dx = (unsigned int)file;    exeLoadParams.envSegment = 0; exeLoadParams.cmdlineOffset = FP_OFF(cmdline); exeLoadParams.cmdlineSegment = FP_SEG(cmdline); // the two FCBs are located at offsets 0x5c and 0x6c in this program's PSP exeLoadParams.fcb1Offset = 0x5c; exeLoadParams.fcb1Segment = _psp; exeLoadParams.fcb2Offset = 0x6c; exeLoadParams.fcb2Segment = _psp; // ES == DS guaranteed? it seems to work rin.x.bx = (unsigned int)&exeLoadParams; intdos(&rin, &rout); // exeLoadParams now contains CS:IP and SS:SP, but what next? } 

Also, what kind of clean-up do I need to do once the program returns? I tried freeing the block whose address I calculated as CS - PSP_SIZE and it seems to have freed most of the memory, but not all of it - in this particular case, 9 paragraphs worth of it were "lost".

How can I properly execute and clean up after a DOS MZ executable loaded into memory with int21 function 4b01h?

Ralf Brown's Interrupt List describes a subvariant of the DOS int21/4Bh function with AL=01, where the program is loaded into memory and a PSP + stack are allocated for it, but the program is not executed. The CS:IP and SS:IP are placed in the parameter block structure that was provided as input in ES:BX.

This works, but what do I need to do in order to execute the program and make sure it returns to the point where I called it from (I am doing this from C, FWIW)? I imagine I can't just cast CS:IP to a void (far *func)(void) and call it a day?

#pragma pack(1) struct { uint16 envSegment; uint16 cmdlineOffset; uint16 cmdlineSegment; uint16 fcb1Offset; uint16 fcb1Segment; uint16 fcb2Offset; uint16 fcb2Segment; uint16 sp; uint16 ss; uint16 ip; uint16 cs; } exeLoadParams; static int loadprog(const char* file, const char far* cmdline) { union REGS rin, rout; rin.h.ah = 0x4B; rin.h.al = 0x1; // DS will be data segment of current executable, no need to provide with intdosx()? rin.x.dx = (unsigned int)file; exeLoadParams.envSegment = 0; exeLoadParams.cmdlineOffset = FP_OFF(cmdline); exeLoadParams.cmdlineSegment = FP_SEG(cmdline); // the two FCBs are located at offsets 0x5c and 0x6c in this program's PSP exeLoadParams.fcb1Offset = 0x5c; exeLoadParams.fcb1Segment = _psp; exeLoadParams.fcb2Offset = 0x6c; exeLoadParams.fcb2Segment = _psp; // ES == DS guaranteed? it seems to work rin.x.bx = (unsigned int)&exeLoadParams; intdos(&rin, &rout); // exeLoadParams now contains CS:IP and SS:SP, but what next? } 

Also, what kind of cleanup do I need to do once the program returns? I tried freeing the block whose address I calculated as CS - PSP_SIZE and it seems to have freed most of the memory, but not all of it - in this particular case, 9 paragraphs worth of it were "lost".

Became Hot Network Question
Spelling and grammar.
Source Link
TonyM
  • 5.3k
  • 1
  • 24
  • 37

How to properly execute and cleanupclean up after a DOS MZ executable loaded into memory with int21 function 4b01h?

Ralf Brown's Interrupt List describes a subvariant of the DOS int21/4Bh function with AL=01, where the program is loaded into memory and a PSP + stack are allocated for it, but the program is not executed. The CS:IP and SS:IP are placed in the parameter block structure that was provided as input in ES:BX.

This works, but what do I need to do in order to execute the program and make sure it returns to the point where I called it from (I am doing this from C, FWIW)? I imagine I can't just cast CS:IP to a void (far *func)(void) and call it a day?

#pragma pack(1) struct { uint16 envSegment; uint16 cmdlineOffset; uint16 cmdlineSegment; uint16 fcb1Offset; uint16 fcb1Segment; uint16 fcb2Offset; uint16 fcb2Segment; uint16 sp; uint16 ss; uint16 ip; uint16 cs; } exeLoadParams; static int loadprog(const char* file, const char far* cmdline) { union REGS rin, rout; rin.h.ah = 0x4B; rin.h.al = 0x1; // DS will be data segment of current executable, no need to provide with intdosx()? rin.x.dx = (unsigned int)file; exeLoadParams.envSegment = 0; exeLoadParams.cmdlineOffset = FP_OFF(cmdline); exeLoadParams.cmdlineSegment = FP_SEG(cmdline); // the two FCBs are located at offsets 0x5c and 0x6c in this program's PSP exeLoadParams.fcb1Offset = 0x5c; exeLoadParams.fcb1Segment = _psp; exeLoadParams.fcb2Offset = 0x6c; exeLoadParams.fcb2Segment = _psp; // ES == DS guaranteed? it seems to work rin.x.bx = (unsigned int)&exeLoadParams; intdos(&rin, &rout); // exeLoadParams now contains CS:IP and SS:SP, but what next? } 

Also, what kind of cleanupsclean-up do I need to do once the program returns? I tried freeing the block whose address I calculated as CS - PSP_SIZE and it seems to have freed most of the memory, but not all of it - in this particular case, 9 paragraphs worth of it were "lost".

How to properly execute and cleanup after a DOS MZ executable loaded into memory with int21 function 4b01h?

Ralf Brown's Interrupt List describes a subvariant of the DOS int21/4Bh function with AL=01, where the program is loaded into memory and a PSP + stack are allocated for it, but the program is not executed. The CS:IP and SS:IP are placed in the parameter block structure that was provided as input in ES:BX.

This works, but what do I need to do in order to execute the program and make sure it returns to the point where I called it from (I am doing this from C, FWIW)? I imagine I can't just cast CS:IP to a void (far *func)(void) and call it a day?

#pragma pack(1) struct { uint16 envSegment; uint16 cmdlineOffset; uint16 cmdlineSegment; uint16 fcb1Offset; uint16 fcb1Segment; uint16 fcb2Offset; uint16 fcb2Segment; uint16 sp; uint16 ss; uint16 ip; uint16 cs; } exeLoadParams; static int loadprog(const char* file, const char far* cmdline) { union REGS rin, rout; rin.h.ah = 0x4B; rin.h.al = 0x1; // DS will be data segment of current executable, no need to provide with intdosx()? rin.x.dx = (unsigned int)file; exeLoadParams.envSegment = 0; exeLoadParams.cmdlineOffset = FP_OFF(cmdline); exeLoadParams.cmdlineSegment = FP_SEG(cmdline); // the two FCBs are located at offsets 0x5c and 0x6c in this program's PSP exeLoadParams.fcb1Offset = 0x5c; exeLoadParams.fcb1Segment = _psp; exeLoadParams.fcb2Offset = 0x6c; exeLoadParams.fcb2Segment = _psp; // ES == DS guaranteed? it seems to work rin.x.bx = (unsigned int)&exeLoadParams; intdos(&rin, &rout); // exeLoadParams now contains CS:IP and SS:SP, but what next? } 

Also, what kind of cleanups do I need to do once the program returns? I tried freeing the block whose address I calculated as CS - PSP_SIZE and it seems to have freed most of the memory, but not all of it - in this particular case, 9 paragraphs worth of it were "lost".

How to properly execute and clean up after a DOS MZ executable loaded into memory with int21 function 4b01h?

Ralf Brown's Interrupt List describes a subvariant of the DOS int21/4Bh function with AL=01, where the program is loaded into memory and a PSP + stack are allocated for it, but the program is not executed. The CS:IP and SS:IP are placed in the parameter block structure that was provided as input in ES:BX.

This works, but what do I need to do in order to execute the program and make sure it returns to the point where I called it from (I am doing this from C, FWIW)? I imagine I can't just cast CS:IP to a void (far *func)(void) and call it a day?

#pragma pack(1) struct { uint16 envSegment; uint16 cmdlineOffset; uint16 cmdlineSegment; uint16 fcb1Offset; uint16 fcb1Segment; uint16 fcb2Offset; uint16 fcb2Segment; uint16 sp; uint16 ss; uint16 ip; uint16 cs; } exeLoadParams; static int loadprog(const char* file, const char far* cmdline) { union REGS rin, rout; rin.h.ah = 0x4B; rin.h.al = 0x1; // DS will be data segment of current executable, no need to provide with intdosx()? rin.x.dx = (unsigned int)file; exeLoadParams.envSegment = 0; exeLoadParams.cmdlineOffset = FP_OFF(cmdline); exeLoadParams.cmdlineSegment = FP_SEG(cmdline); // the two FCBs are located at offsets 0x5c and 0x6c in this program's PSP exeLoadParams.fcb1Offset = 0x5c; exeLoadParams.fcb1Segment = _psp; exeLoadParams.fcb2Offset = 0x6c; exeLoadParams.fcb2Segment = _psp; // ES == DS guaranteed? it seems to work rin.x.bx = (unsigned int)&exeLoadParams; intdos(&rin, &rout); // exeLoadParams now contains CS:IP and SS:SP, but what next? } 

Also, what kind of clean-up do I need to do once the program returns? I tried freeing the block whose address I calculated as CS - PSP_SIZE and it seems to have freed most of the memory, but not all of it - in this particular case, 9 paragraphs worth of it were "lost".

edited tags
Link
user3840170
  • 27.4k
  • 4
  • 110
  • 170
Avoid subjecting people to porn ads.
Source Link
Stephen Kitt
  • 139.8k
  • 19
  • 578
  • 536
Loading
Source Link
Loading