Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to call EXT command?

Status
Not open for further replies.

syskplim

Technical User
Nov 17, 2003
46
MY
This is a batch sample:

@ echo off
edit %1.asm
ml %1.asm
cls

We can call an External command like EDIT.COM and ML.EXE from a batch.

How can i do that in ASM? how abt if i want to write above coding in ASM and compile it to COM or EXE? not BAT2EXE.




---->ASM fresher need help!<----

With kind regards.
syskplim@streamyx.com
 
Hi, syskplim.

Int 21h function 4bh Execute Program.

ah = 4bh
al = 00h Load & execute program

es:bx = segment:eek:ffset of parameter block
ds:dx = segment:eek:ffset of ASCIIZ program pathname.

returns: carry flag clear if successful, else
carry flag set with error code in AX

hope this helps
rgds
Zeit.
 
Here's a bit of code to illustrate.
It is part of an exe file, not a com file.

Path db 'C:\dos\tree.com',0 ;asciiz command string

Parms dw 0 ;parent env block is ok
dw OFFSET CmdTail ;command tail address
dw SEG CmdTail
dw 0,0 ;fcb pointers don't matter
dw 0,0 ;ditto

CmdTail db 3 ;length of command tail
db 'C:\',13 ;actual command tail

SaveSS DW 0 ;temporary storage
SaveSP dw 0
Error dw 0

.....
mov bx,ds ;point to start of data segment
mov ax,es ;point to start of psp
sub bx,ax ;number of segments for code and data
mov ax,sp ;points to top of stack
mov cl,4
shr ax,cl ;bytes to paragraphs
add bx,ax ;bx = paragraphs needed
mov ah,4ah ;modify memory allocation of this program to give space to use exec
int 21h ;call dos


mov Error, 0 ;clr Eerror
mov ah,4bh ;exec function
mov al,0 ;load & execute
mov dx,OFFSET Path ;address of the asciiz command string in the data seg
push ds ;get ds segment
pop es ;into es for int21 call
mov bx,OFFSET Parms ;parameter block address
mov SaveSS,SS ;save SS reg
mov SaveSP,SP ;save SP reg
int 21h ;call dos
jnc no_error ;carry clear if no error

mov Error,ax ;save error

no_error:
mov SS,SaveSS ;restore SP:SS
mov SP,SaveSP

cmp Error,0 ;any error
je ok ;no error

error handling code here

ok:



This is a precis of some code found in &quot;Advanced Assembly Language&quot; by Allen L. Wyatt.

Hope it helps.
rgds
Zeit.
 
The code I posted above depends for its proper function on directives used in MASM 6 which appear to set up the segments in a specific way so that DS and SS point to the same segment.

The directives are (for the data/stack segment)

.MODEL small
.STACK
.DATA

For the code segment

.CODE
.STARTUP
and
.EXIT

If this isn't the case, it falls over. Spectacularly.

Particularly if you use old versions of MASM (like me).

I'm currently playing about with this to sort things out.

rgds
Zeit.
 
This seems to work:

DATA SEGMENT PARA 'Data'

Path db 'C:\asm\callext4.exe',0 ;asciiz command string

Parms dw 0 ;parent env block is ok
dw OFFSET CmdTail ;command tail address
dw SEG CmdTail
dw 0,0 ;fcb pointers don't matter
dw 0,0 ;ditto

CmdTail db 3 ;length of command tail
db 'C:\',13 ;actual command tail

SaveSS DW 0 ;temporary storage
SaveSP dw 0
Error dw 0

Message1 db 'Press any key to enter child program...$'
Message2 db 13,10,'Back from child program',13,10,'$'
Message3 db 'Ending parent program'
CRLF DB 13,10,'$'
ErrMsg db 'Error during EXEC function: $'

ErrorTable dw offset ErrorX
dw offset Error1
dw offset Error2
dw offset Error3
dw offset Error4
dw offset Error5
dw offset ErrorX
dw offset ErrorX
dw offset Error8
dw offset ErrorX
dw offset ErrorA
dw offset ErrorB

Error1 db ' (invalid function)$'
Error2 db ' (file not found)$'
Error3 db ' (path not found)$'
Error4 db ' (too many open files)$'
Error5 db ' (access denied)$'
Error8 db ' (not enough memory)$'
ErrorA db ' (bad environment)$'
ErrorB db ' (bad Format)$'
ErrorX db ' (unknown error value)$'

sscsmsg db 'cs reg == ss reg! I',027h,'m amazed!$'
ssltcsmsg db 'ss is less than cs!$'
ssltdsmsg db 'ss is less than ds!$'

CR EQU 0DH
LF EQU 0AH
BEL EQU 07H

q db 'Register values at entry',CR,LF,'cs:ip '
csstr db 'xxxx:'
ipstr db 'xxxx ds '
dsstr db 'xxxx:xxxx ss:sp '
ssstr db 'xxxx:'
spstr db 'xxxx es '
esstr db 'xxxx:xxxx ',CR,LF
db 'Program Data Segment at '
newds db 'xxxx:xxxx',CR,LF,'$'

oldds dw 0 ;DS register on entry
oldss dw 0 ;SS register on entry

oldcs dw 0 ;CS register on entry
oldip dw 0 ;IP register on entry
oldes dw 0 ;ES register on entry



end_of_ds equ $

DATA ENDS

CODE SEGMENT PARA 'Code'

ASSUME CS:CODE,DS:DATA,ES:CODE,SS:STACK

Exec1 proc far
call get_ip ;get instruction pointer into ax

jmp CONV_START ;don't mess with the stack yet

callext4: ;return here from register display

mov ax,ss ;SS should be > ds
mov bx,ds
cmp bx,ax ;ss>ds sets cy

jz ss_eq_ds ;original code assumes this

jc ss_gt_ds

mov dx,offset ssltdsmsg ;ss < ds don't expect this
mov ah,9
int 21h
jmp exit ;give up


ss_gt_ds: ;SS > DS
mov ax,ss ;stack seg
push cs
pop bx ;code seg
cmp bx,ax ;ss>cs sets cy

jz ss_eq_cs_gt_ds ;this is very unlikely

jc ss_gt_cs_gt_ds ;this is what the code originally expected

mov dx,offset ssltcsmsg ;ss < cs don't expect this
mov ah,9 ;prn string
int 21h ;call dos
jmp exit ;give up


ss_eq_cs_gt_ds:
mov dx,offset sscsmsg
mov ah,9 ;print msg
int 21h
jmp exit ;give up

ss_gt_cs_gt_ds:
mov bx,ss ;this is the most likely
mov ax,es
sub bx,ax ;get number of paragraphs
;between psp and bottom of stack
jmp add_stack_len

ss_eq_ds: ;ss == ds
mov bx,ds ;point to start of data segment
mov ax,es ;point to start of psp
sub bx,ax ;number of segments for code and data

add_stack_len:
mov ax,sp ;points to top of stack (byte pointer)
mov cl,4
shr ax,cl ;bytes to paragraphs
add bx,ax ;bx = paragraphs needed

mov ah,4ah ;modify memory allocation of this program to give space to use exec
int 21h ;call dos

mov dx,offset Message1 ;starting message
mov ah,9 ;display string
int 21h ;call dos

mov ah,0 ;read kb chr
int 16h ;call bios

cmp al,27 ;esc?
jnz not_esc
jmp exit ;ESC: terminate program & return to dos

not_esc:

mov dx,offset CRLF
mov ah,9
int 21h ;print CRLF

mov Error, 0 ;clr Error
mov ah,4bh ;exec function
mov al,0 ;load & execute
mov dx,OFFSET Path ;address of the asciiz command string in the data seg
push ds ;get ds segment
pop es ;into es for int21 call
mov bx,OFFSET Parms ;parameter block address
mov SaveSS,SS ;save SS reg
mov SaveSP,SP ;save SP reg
int 21h ;call dos

jnc no_error ;carry clear if no error

mov Error,ax ;save error

no_error:
mov SS,SaveSS ;restore SP:SS (may be corrupted by dos)
mov SP,SaveSP

mov dx,offset Message2 ;point to return message
mov ah,9 ;dos print string
int 21h ;call dos

cmp Error,0 ;any error
je ok ;no error

mov dx,offset ErrMsg ;point to error message
mov ah,9
int 21h ;dos prn string

mov ax,Error ;get error valuve
Call PrtDec ;and print it

mov bx,Error ;get error value
shl bx,1 ;times 2
mov dx,ErrorTable[BX] ;get the error message address
mov ah,9
int 21h ;dos print string

mov dx,offset CRLF
mov ah,9
int 21h ;dos print string

ok:
mov dx,offset Message3 ;exit message
mov ah,9
int 21h ;dos print string

exit:
mov ax,4c01h ;exit with error 0
int 21h ;return to dos


Exec1 endp

PrtDec proc near
push ax
push cx
push dx

mov cx,0ffffh ;ending flag
push cx
mov cx,10
pd1:
mov dx,0
div cx ;divide by 10
add dl,30h ;to ascii
push dx
cmp ax,0 ;all done?
jne pd1

pd2:
pop dx ;get chr
cmp dx,0ffffh ;end?
je pd3

mov ah,02h ;prn chr
int 21h ;call dos
jmp pd2 ;do next chr
pd3:
pop dx
pop cx
pop ax
ret
PrtDec endp

cs_end equ $

; CONVPROG displays the contents of CS:IP, DS:xx ES:xx
; and SS:SP

CONVPROG proc

CONV_START:
push ax ;save the ip value held in ax
push cs ;save cs reg
push ds ;save ds reg

MOV AX,DATA ;initialize DS to data segment
MOV DS,AX

pop ax ;get original ds
mov oldds,ax ;save original ds
mov ax,es ;save es
mov oldes,ax
mov ax,ss ;save ss
mov oldss,ax
pop ax ;get cs
mov oldcs,ax ;save cs
pop ax ;get original ip
mov oldip, ax


mov bx,offset csstr ;pointer to CS address in message
mov ax,oldcs
call hex4asc ;hex to 4 ascii chrs

mov bx,offset ipstr ;ptr to IP address in message
mov ax,oldip
call hex4asc ;hex to 4 ascii chrs


mov bx,offset dsstr ;ptr to DS address in msg
mov ax,oldds
call hex4asc ;hex to 4 ascii chrs

mov bx, offset ssstr ;ptr to SS address in msg
mov ax,oldss
call hex4asc ;hex to 4 ascii chrs

mov bx,offset esstr
mov ax,oldes
call hex4asc ;hex to 4 ascii chrs

mov ax,sp
mov bx, offset spstr
call hex4asc ;hex to 4 ascii chrs

push ds
pop ax
mov bx,offset newds
call hex4asc ;hex to 4 ascii chrs

MOV DX,OFFSET q ;register values msg
MOV AH,9 ;display it
INT 21H ;call dos

jmp callext4 ;return to &quot;caller&quot;

CONVPROG endp ;add end proc

get_ip proc near
pop ax ;get return address into ax
push ax
sub ax,3 ;and subtract 3 to get orignal ip
ret
get_ip endp

; hex1asc converts the ls nibble of AL into ascii & stores it [bx]
; bumps BX.
; in: AL and BX
; out: AL corrupted, BX bumped
;
hex1asc proc near ;convert ls nibble in AL to ascii & store at [bx]
and al,0fh
add al,'0'
cmp al,'9'
jle not_alpha
add al,'a'-'9'-1
not_alpha:
mov [ds:bx],al ;store at ds:bx
inc bx ;bump pointer bx
ret

hex1asc endp

; hex2asc converts AL to two ascii chrs at [BX]
; in: AL and BX
; out: AL unchanged, BX=BX+2
;
hex2asc proc near ;convert AL to two ascii chrs and store at [bx]
push ax

and al,0f0h
shr al,1
shr al,1
shr al,1
shr al,1
call hex1asc ;convert ms nibble to ascii

pop ax
push ax

call hex1asc ;convert ls nibble to ascii

pop ax
ret
hex2asc endp

; hex4asc converts AX to 4 ascii chars and stores at [BX]
; in: AX with BX pointing to output string
; out: AX unchanged with BX=BX+4
;
hex4asc proc near ;convert AX to ascii and store [bx]
push ax

mov al,ah
call hex2asc ;convert 2 ms digits to ascii

pop ax ;restore ax
push ax
call hex2asc ;convert 2 ls digits to ascii

pop ax
ret
hex4asc endp


CODE ENDS

STACK segment para stack 'STACK'
db 1024 dup ('x')
STACK ENDS

END Exec1 ;start address

Assemble it to an exe file.

It shows its own loading address and register contents, then spawns another version of itself ad infinitum, or until you hit ESC, at which time it exits.

Hope that's of some help
rgds
Zeit.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top