home *** CD-ROM | disk | FTP | other *** search
/ Complete Bookshop / CompleteWorkshop.iso / compute / dosexec / parent.asm < prev    next >
Assembly Source File  |  1989-06-07  |  5KB  |  221 lines

  1.     name    parent
  2.     title    'PARENT --- demonstrate EXEC call'
  3. ;
  4. ; PARENT.EXE --- demonstration of EXEC to run process
  5. ;
  6. ; Uses MS-DOS EXEC (Int 21H, Function 4BH Subfunction 00H)
  7. ; to load and execute a child process named CHILD.EXE,
  8. ; then displays CHILD's return code.
  9. ;
  10. ; Ray Duncan, June 1987
  11. ;
  12.  
  13. stdin    equ    0    ; standard input
  14. stdout    equ    1    ; standard output
  15. stderr    equ    2    ; standard error
  16.  
  17. stksize equ    128    ; size of stack
  18.  
  19. cr    equ    0dh    ; ASCII carriage return
  20. lf    equ    0ah    ; ASCII linefeed
  21.  
  22.  
  23. DGROUP    group    _DATA,_ENVIR,_STACK
  24.  
  25.  
  26. _TEXT    segment byte public 'CODE'    ; executable code segment
  27.  
  28.     assume  cs:_TEXT,ds:_DATA,ss:_STACK
  29.  
  30.  
  31. stk_seg dw    ?    ; original SS contents
  32. stk_ptr dw    ?    ; original SP contents
  33.  
  34.  
  35. main    proc    far    ; entry point from MS-DOS
  36.  
  37.     mov    ax,_DATA    ; set DS = our data segment
  38.     mov    ds,ax
  39.  
  40.             ; now give back extra memory
  41.             ; so child has somewhere to 
  42.             ; run...
  43.     mov    ax,es    ; let AX = segment of PSP base
  44.     mov    bx,ss    ; and BX = segment of stack base
  45.     sub    bx,ax    ; reserve seg stack - seg psp
  46.     add    bx,stksize/16    ; plus paragraphs of stack
  47.     mov    ah,4ah    ; fxn 4ah = modify memory 
  48.             ; block
  49.     int    21h
  50.     jc    main1
  51.             ; display parent message ...
  52.     mov    dx,offset DGROUP:msg1    ; DS:DX = address of message
  53.     mov    cx,msg1_len    ; CX = length of message
  54.     call    pmsg
  55.  
  56.     push    ds    ; save parent's data segment
  57.     mov    stk_seg,ss    ; save parent's stack pointer
  58.     mov    stk_ptr,sp
  59.  
  60.             ; now EXEC the child process...
  61.     mov    ax,ds    ; set ES = DS
  62.     mov    es,ax
  63.     mov    dx,offset DGROUP:cname    ; DS:DX = child pathname
  64.     mov    bx,offset DGROUP:pars    ; EX:BX = parameter block
  65.     mov    ax,4b00h    ; function 4BH, subfunction 00H
  66.     int    21h    ; transfer to MS-DOS
  67.  
  68.     cli        ; (for bug in some early 8088s)
  69.     mov    ss,stk_seg    ; restore parent's stack  
  70.             ; pointer
  71.     mov    sp,stk_ptr
  72.     sti        ; (for bug in some early 8088s)
  73.     pop    ds    ; restore DS = our data segment
  74.  
  75.     jc    main2    ; jump if EXEC failed
  76.  
  77.             ; otherwise EXEC succeeded,
  78.             ; convert and display child's
  79.             ; termination and return 
  80.             ; codes...
  81.     mov    ah,4dh    ; fxn 4dh = get return code
  82.     int    21h    ; transfer to MS-DOS
  83.     xchg    al,ah    ; convert termination code
  84.     mov    bx,offset DGROUP:msg4a
  85.     call    b2hex
  86.     mov    al,ah    ; get back return code
  87.     mov    bx,offset DGROUP:msg4b    ; and convert it
  88.     call    b2hex
  89.     mov    dx,offset DGROUP:msg4    ; DS:DX = address of message
  90.     mov    cx,msg4_len    ; CX = length of message
  91.     call    pmsg    ; display it
  92.  
  93.     mov    ax,4c00h    ; no error, terminate program
  94.     int    21h    ; with return code = 0
  95.  
  96. main1:    mov    bx,offset DGROUP:msg2a    ; convert error code
  97.     call    b2hex
  98.     mov    dx,offset DGROUP:msg2    ; display message 'Memory
  99.     mov    cx,msg2_len    ; resize failed...'
  100.     call    pmsg
  101.     jmp    main3
  102.  
  103. main2:    mov    bx,offset DGROUP:msg3a    ; convert error code
  104.     call    b2hex
  105.     mov    dx,offset DGROUP:msg3    ; display message 'EXEC
  106.     mov    cx,msg3_len    ; call failed...'
  107.     call    pmsg
  108.  
  109. main3:    mov    ax,4c01h    ; error, terminate program
  110.     int    21h    ; with return code = 1
  111.  
  112. main    endp        ; end of main procedure
  113.  
  114.  
  115. b2hex    proc    near    ; convert byte to hex ASCII
  116.             ; call with AL=binary value
  117.             ;    BX=addr to store string
  118.     push    ax
  119.     shr    al,1
  120.     shr    al,1
  121.     shr    al,1
  122.     shr    al,1
  123.     call    ascii    ; become first ASCII character
  124.     mov    [bx],al    ; store it
  125.     pop    ax
  126.     and    al,0fh    ; isolate lower 4 bits, which
  127.     call    ascii    ; become the second ASCII 
  128.             ; character
  129.     mov    [bx+1],al    ; store it
  130.     ret
  131. b2hex    endp
  132.  
  133.  
  134. ascii    proc    near    ; convert value 00-0FH in AL
  135.     add    al,'0'    ; into a "hex ASCII" character
  136.     cmp    al,'9'
  137.     jle    ascii2    ; jump if in range 00-09H,
  138.     add    al,'A'-'9'-1    ; offset it to range 0A-0FH,
  139.  
  140. ascii2:    ret        ; return ASCII char. in AL.
  141. ascii   endp
  142.  
  143.  
  144. pmsg    proc    near    ; displays message on 
  145.             ; standard output
  146.             ; call with DS:DX = address,
  147.             ;                      CX = length
  148.  
  149.     mov    bx,stdout    ; BX = standard output handle
  150.     mov    ah,40h    ; function 40h = write 
  151.             ; file/device
  152.     int    21h    ; transfer to MS-DOS
  153.     ret        ; back to caller
  154.  
  155. pmsg    endp
  156.  
  157. _TEXT    ends
  158.  
  159.  
  160. _DATA    segment para public 'DATA'    ; static & variable data segment
  161.  
  162. cname    db    'CHILD.EXE',0    ; pathname of child process
  163.  
  164. pars    dw    _ENVIR    ; segment of environment block
  165.     dd    tail    ; long address, command tail
  166.     dd    fcb1    ; long address, default FCB #1
  167.     dd    fcb2    ; long address, default FCB #2
  168.  
  169. tail    db    fcb1-tail-2    ; command tail for child
  170.     db    'dummy command tail',cr
  171.             
  172. fcb1    db    0    ; copied into default FCB #1 in
  173.     db    11 dup (' ')    ; child's program segment prefix
  174.     db    25 dup (0)
  175.  
  176. fcb2    db    0    ; copied into default FCB #2 in
  177.     db    11 dup (' ')    ; child's program segment prefix
  178.     db    25 dup (0)
  179.  
  180. msg1    db    cr,lf,'Parent executing!',cr,lf
  181. msg1_len equ     $-msg1
  182.  
  183. msg2    db    cr,lf,'Memory resize failed, error code='
  184. msg2a    db    'xxh.',cr,lf
  185. msg2_len equ     $-msg2
  186.  
  187. msg3    db    cr,lf,'EXEC call failed, error code='
  188. msg3a    db    'xxh.',cr,lf
  189. msg3_len equ     $-msg3
  190.  
  191. msg4    db    cr,lf,'Parent regained control!'
  192.     db    cr,lf,'Child termination type='
  193. msg4a     db    'xxh, return code='
  194. msg4b    db    'xxh.',cr,lf
  195. msg4_len equ     $-msg4
  196.  
  197. _DATA    ends
  198.  
  199.  
  200. _ENVIR  segment para public 'DATA'    ; example environment block
  201.             ; to be passed to child
  202.  
  203.     db    'PATH=',0    ; basic PATH, PROMPT,
  204.     db    'PROMPT=$p$_$n$g',0    ; and COMSPEC strings
  205.     db    'COMSPEC=C:\COMMAND.COM',0
  206.     db    0    ; extra null terminates block
  207.  
  208. _ENVIR    ends
  209.  
  210.  
  211. _STACK    segment para stack 'STACK'
  212.  
  213.  
  214.     db    stksize dup (?)
  215.  
  216. _STACK    ends
  217.  
  218.  
  219.     end    main    ; defines program entry point
  220.  
  221.