Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Calling Another Program...

pmcastillopmcastillo Posts: 140Member
How to call another program using assembly?

Comments

  • anthrax11anthrax11 Posts: 511Member
    : How to call another program using assembly?
    :

    For that we have Interrupt 21h function 4bh(EXEC load and/or execute program)
    [code]
    mov ah,4bh ;Function 4bh
    mov al,0 ;0 = load and execute
    mov dx,offset ProgramName ;Pointer to the program name(Segment DS)
    mov bx,offset ParamBlock ;Pointer to the parameter block(see below)
    mov es,seg ParamBlock ;Segment of the parameter block


    ;Format of EXEC parameter block for AL=00h,01h,04h:

    ; 00h WORD segment of environment to copy for child
    ;process (copy caller's environment if 0000h)
    ; 02h DWORD pointer to command tail to be copied into child's PSP
    ; 06h DWORD pointer to first FCB to be copied into child's PSP
    ; 0Ah DWORD pointer to second FCB to be copied into child's PSP

    ; 0Eh DWORD doesnt concern al=0
    ; 12h DWORD doesnt concern al=0

    ProgramName db "Program.exe$" ;Name of the program(with extension!)
    [/code]
    Take a look at Ralf Browns Interrupt list(INTERRUP.G) for further details.
  • pmcastillopmcastillo Posts: 140Member
    Now, I know that, INT 21H/AH=4BH is the function for "LOADING AND/OR EXECUTING A PROGRAM". I tried to look at Ralph Brown's Interrupt List (http://www.ctyme.com/intr/rb-2939.htm) but it was so many things! It confused me! So, I tried to "verbatimly" put the code in my program, but it still don't work. Here's my code: (I'm using TASM for DOS-based Programs)

    [CODE]
    .MODEL TINY
    .CODE
    ORG 0100H

    MAIN:
    JMP START
    ProgramName DB "TEST.COM$"
    ParamBlock DB "$"

    START:
    mov ah,4bh ;Function 4bh
    mov al,0 ;0 = load and execute
    mov dx,offset ProgramName ;Pointer to the program name
    mov bx,offset ParamBlock ;Pointer to the parameter block

    mov DS,DX
    mov es,BX
    INT 21H

    INT 20H
    END MAIN
    END
    [/CODE]

    Also, is the

    [CODE]
    mov DS,DX
    mov es,BX
    [/CODE]

    Right?



  • jeffleydajeffleyda Posts: 390Member
    : Also, is the
    :
    : [CODE]
    : mov DS,DX
    : mov es,BX
    : [/CODE]
    :
    : Right?

    Almost. Memory addressing is done in segment:offset mode. You've properly got the offset part right, but here your setting the segment equal to the offset, which isn't pointing where you want it to.

    Luckily, you've got your program defined as a DOS .COM file, so at startup all of your segments are the same anyway. You can actually just eliminate that code and the segments will be pointing where you want them.

    It's good for safety reasons to set up the segments properly, as you can't always assume your segments are what you think they are as your program executes. Here's one of a thousand ways to do it:

    [code]
    push cs
    pop ds
    push cs
    pop es
    [/code]

    That will set DS and ES to whatever CS is.

    This program may still not work-you probably need to free up some memory for the new program to load into before it'll work. This is yet another headache you're going to have to deal with. Welcome to assembly!

    -jeff!


  • anthrax11anthrax11 Posts: 511Member
    : Now, I know that, INT 21H/AH=4BH is the function for "LOADING AND/OR EXECUTING A PROGRAM". I tried to look at Ralph Brown's Interrupt List (http://www.ctyme.com/intr/rb-2939.htm) but it was so many things! It confused me! So, I tried to "verbatimly" put the code in my program, but it still don't work. Here's my code: (I'm using TASM for DOS-based Programs)
    :
    : [CODE]
    : .MODEL TINY
    : .CODE
    : ORG 0100H
    :
    : MAIN:
    : JMP START
    : ProgramName DB "TEST.COM$"
    : ParamBlock DB "$"
    :
    : START:
    : mov ah,4bh ;Function 4bh
    : mov al,0 ;0 = load and execute
    : mov dx,offset ProgramName ;Pointer to the program name
    : mov bx,offset ParamBlock ;Pointer to the parameter block
    :
    : mov DS,DX
    : mov es,BX
    : INT 21H
    :
    : INT 20H
    : END MAIN
    : END
    : [/CODE]
    :
    : Also, is the
    :
    : [CODE]
    : mov DS,DX
    : mov es,BX
    : [/CODE]
    :
    : Right?
    :
    :
    [blue]
    OK, to be honest, it was confusing for me too.
    I was going to tell you that you should read the com file to the memory and then jump to it, but when I ran it, some weird stuff happened.

    Heres what I tried:

    1)First open the com file
    2)Then read it to the memory (to 100h)
    3)Then jump to 2 bytes before the program(100h-2), where I had previously written the opcode for int 21h (021CDh)
    4)Run the next program from cs:100h(which is right after my int 21h at cs:0feh)

    When I compiled and run it, Windows gave a really fun error about me using a disk utility designed for an earlier version of DOS:P.
    Perhaps it works under pure DOS, I dont know...
    Here's the code:
    [code]
    .MODEL TINY
    .CODE
    ORG 0100H
    MAIN:

    START:
    mov word ptr[si+0feh],21cdh
    mov jmpcomseg,cs

    mov ah,3dh
    mov dx,offset ProgramName
    int 21h ;Open the COM file
    mov ProgHnd,ax

    mov ah,3fh
    mov bx,ProgHnd
    mov cx,72
    mov dx,100h
    ;int 21h is at cs:0feh

    db 0eah ;jmp far 0feh (100h-2)
    dw 0feh
    jmpcomseg dw ?

    ProgramName DB "myprog.com$"
    ProgHnd dw ?
    Comspace db 4096 dup(?) ;Some additional space for the next program

    END MAIN
    END
    [/code]

    Now I dont know what else to tell you:P You should still probably use INT 21H/AH=4BH and look for some sample code somewhere because Ive never used this function before. Good luck!
    [/blue]

  • pmcastillopmcastillo Posts: 140Member
    [code]
    : .MODEL TINY
    : .CODE
    : ORG 0100H
    : MAIN:
    :
    : START:
    : mov word ptr[si+0feh],21cdh
    : mov jmpcomseg,cs
    :
    : mov ah,3dh
    : mov dx,offset ProgramName
    : int 21h ;Open the COM file
    : mov ProgHnd,ax
    :
    : mov ah,3fh
    : mov bx,ProgHnd
    : mov cx,72
    : mov dx,100h
    : ;int 21h is at cs:0feh
    :
    : db 0eah ;jmp far 0feh (100h-2)
    : dw 0feh
    : jmpcomseg dw ?
    :
    : ProgramName DB "myprog.com$"
    : ProgHnd dw ?
    : Comspace db 4096 dup(?) ;Some additional space for the next program
    :
    : END MAIN
    : END
    [/code]

    The code "FREAKED" me out =) . Especial that "mov word ptr[si+0feh],21cdh" statement. Can't undestand some of the statements... =P
  • IDKIDK Posts: 1,784Member
    Just a thought...

    When you read the program to memmory, wont it overwrite the loading program? Both program's can't start at 100h...

    If this is the case, solve it by allocating some memmory for the loading program, and then run it...

    The one and only [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]

  • shaolin007shaolin007 Posts: 1,018Member
    : : Now, I know that, INT 21H/AH=4BH is the function for "LOADING AND/OR EXECUTING A PROGRAM". I tried to look at Ralph Brown's Interrupt List (http://www.ctyme.com/intr/rb-2939.htm) but it was so many things! It confused me! So, I tried to "verbatimly" put the code in my program, but it still don't work. Here's my code: (I'm using TASM for DOS-based Programs)
    : :
    : : [CODE]
    : : .MODEL TINY
    : : .CODE
    : : ORG 0100H
    : :
    : : MAIN:
    : : JMP START
    : : ProgramName DB "TEST.COM$"
    : : ParamBlock DB "$"
    : :
    : : START:
    : : mov ah,4bh ;Function 4bh
    : : mov al,0 ;0 = load and execute
    : : mov dx,offset ProgramName ;Pointer to the program name
    : : mov bx,offset ParamBlock ;Pointer to the parameter block
    : :
    : : mov DS,DX
    : : mov es,BX
    : : INT 21H
    : :
    : : INT 20H
    : : END MAIN
    : : END
    : : [/CODE]
    : :
    : : Also, is the
    : :
    : : [CODE]
    : : mov DS,DX
    : : mov es,BX
    : : [/CODE]
    : :
    : : Right?
    : :
    : :
    : [blue]
    : OK, to be honest, it was confusing for me too.
    : I was going to tell you that you should read the com file to the memory and then jump to it, but when I ran it, some weird stuff happened.
    :
    : Heres what I tried:
    :
    : 1)First open the com file
    : 2)Then read it to the memory (to 100h)
    : 3)Then jump to 2 bytes before the program(100h-2), where I had previously written the opcode for int 21h (021CDh)
    : 4)Run the next program from cs:100h(which is right after my int 21h at cs:0feh)
    :
    : When I compiled and run it, Windows gave a really fun error about me using a disk utility designed for an earlier version of DOS:P.
    : Perhaps it works under pure DOS, I dont know...
    : Here's the code:
    : [code]
    : .MODEL TINY
    : .CODE
    : ORG 0100H
    : MAIN:
    :
    : START:
    : mov word ptr[si+0feh],21cdh
    : mov jmpcomseg,cs
    :
    : mov ah,3dh
    : mov dx,offset ProgramName
    : int 21h ;Open the COM file
    : mov ProgHnd,ax
    :
    : mov ah,3fh
    : mov bx,ProgHnd
    : mov cx,72
    : mov dx,100h
    : ;int 21h is at cs:0feh
    :
    : db 0eah ;jmp far 0feh (100h-2)
    : dw 0feh
    : jmpcomseg dw ?
    :
    : ProgramName DB "myprog.com$"
    : ProgHnd dw ?
    : Comspace db 4096 dup(?) ;Some additional space for the next program
    :
    : END MAIN
    : END
    : [/code]
    :
    : Now I dont know what else to tell you:P You should still probably use INT 21H/AH=4BH and look for some sample code somewhere because Ive never used this function before. Good luck!
    : [/blue]
    :
    :
    [green]
    Quick question, would the DS be different with the called program? How would the program know which DS to use? I have never called another program from assembly before and was curious.
    [/green]


  • jeffleydajeffleyda Posts: 390Member
    Here's a sample DOS call routine I've got tucked away in my asm directory. I don't remember if I wrote this or not, but I can certainly see that I didn't comment it! ;)

    I just compiled and ran it under windows XP dos, so it should work on anything prior to that too. Calls a batch file called mybatch.bat, which I had simply do a DIR on the current directory.
    [code]
    .model small
    .code
    ORG 100H
    main: Jmp start

    save_ss dw ?
    save_sp dw ?
    cmd1len db 7 ; length of the cmd
    cmd1txt db 'mybatch',0dh,0 ; batch file to call

    start:
    push ax
    push bx
    push cx
    push dx
    Mov bx,offset endflag
    mov cl,4
    shr bx,cl
    inc bx
    mov ax,cs
    mov es,ax
    mov ah,4ah
    int 21h
    mov ax,cs
    mov ds,ax
    mov ax,offset cmd1len
    mov si,ax

    mov ax,ss
    mov save_ss,ax
    mov save_sp,sp
    int 2eh

    Mov ax,cs:save_ss
    mov ss,ax
    mov sp,cs:save_sp
    pop dx
    pop cx
    pop bx
    pop ax

    exit:
    mov ax,4c00h
    int 21h
    endflag label near

    END MAIN
    [/code]

    Sorry about the lack of comments. I'm sure if I stare at this hard enough I can figure out what it's doing, so if you have any questions, let me know. You should be able to replace the batch file with another .COM file or .EXE. I've used similar code to add a DOS shell feature to one of my applications.

    -jeff!
  • anthrax11anthrax11 Posts: 511Member
    [b][red]This message was edited by anthrax11 at 2005-10-20 2:34:15[/red][/b][hr]
    : Just a thought...
    :
    : When you read the program to memmory, wont it overwrite the loading program? Both program's can't start at 100h...
    :
    : If this is the case, solve it by allocating some memmory for the loading program, and then run it...
    :
    : The one and only [b]Niklas Ulvinge[/b] [white]aka [b]IDK[/b][/white]
    :
    :
    Yes, that was the idea, to overwrite it. It was a bad idea, forget it.

    OK, I tried allocating memory, but for some reason I always get an insufficient memory error(8), even if I try to get like 32 bytes or so. I dont know if the rest of the code works:

    [code]
    .MODEL TINY
    .CODE
    ORG 0100H
    MAIN:

    START:
    mov ah,48h ;Function 48h(Allocate memory)
    mov bx,4 ;Number of 16-byte blocks to allocate
    int 21h ;Do it
    jc err_exit ;Exit if an error occurs(it does)
    mov jmpcomseg,ax ;Int 21h returns the segment in ax

    mov ah,3dh ;Function 3dh(open file)
    mov al,0 ;Open for reading
    mov dx,offset ProgramName ;Offset to the program
    int 21h ;Open the COM file
    mov ProgHnd,ax ;Save the file handle

    mov ds,jmpcomseg ;Read to the allocated
    mov dx,100h ;memory
    mov ah,3fh ;Function 3fh(read file)
    mov bx,ProgHnd ;Get the handle we saved earlier
    mov cx,64 ;Read 64 bytes(size of the program)
    int 21h ;Read from the file

    db 0eah ;jmp far jmpcomseg:100h
    dw 0100h ;(Jump to the program)
    jmpcomseg dw ?

    err_exit:
    ret

    ProgramName DB "my_prog.com$"
    ProgHnd dw ?

    END MAIN
    END
    [/code]
    Btw, I didn't get the automatic notification thingy. Whats up?
    My e-mail provider(live.hot.ee) is going through major changes and everyones flaming them because of all the bugs, maybe thats the problem, I dont know.

    [blue]Haha, Got all the letters 2 minutes after posting never mind then.[/blue]

  • pmcastillopmcastillo Posts: 140Member
    [code]
    : .MODEL TINY
    : .CODE
    : ORG 0100H
    : MAIN:
    :
    : START:
    : mov ah,48h ;Function 48h(Allocate memory)
    : mov bx,4 ;Number of 16-byte blocks to allocate
    : int 21h ;Do it
    : jc err_exit ;Exit if an error occurs(it does)
    : mov jmpcomseg,ax ;Int 21h returns the segment in ax
    :
    : mov ah,3dh ;Function 3dh(open file)
    : mov al,0 ;Open for reading
    : mov dx,offset ProgramName ;Offset to the program
    : int 21h ;Open the COM file
    : mov ProgHnd,ax ;Save the file handle
    :
    : mov ds,jmpcomseg ;Read to the allocated
    : mov dx,100h ;memory
    : mov ah,3fh ;Function 3fh(read file)
    : mov bx,ProgHnd ;Get the handle we saved earlier
    : mov cx,64 ;Read 64 bytes(size of the program)
    : int 21h ;Read from the file
    :
    : db 0eah ;jmp far jmpcomseg:100h
    : dw 0100h ;(Jump to the program)
    : jmpcomseg dw ?
    :
    : err_exit:
    : ret
    :
    : ProgramName DB "my_prog.com$"
    : ProgHnd dw ?
    :
    : END MAIN
    : END
    [/code]


    Yipee! A Code with Comments! Now I'll just have to DIGEST it... Thanks everyone! I'll just post if I have concerns.... =)
Sign In or Register to comment.