Program Example 1



Figure 2-4.

ARGC.ASM, a routine that returns the number of command-tail arguments.

---------------------------------------------------------------------------------------------------

title ARGC.ASM --- Return Number of Arguments

page 55,132

; ARGC.ASM --- Return number of command line arguments. Treats blanks

; and tabs as whitespace, carriage return as terminator,

; text enclosed in quotation marks as a single argument.

;

; Copyright (C) 1989 Ray Duncan

;

; Call with: ES:BX = command line

;

; Returns: AX = argument count (always >=1)

;

; Destroys: Nothing

cr equ 0dh ; ASCII carriage return

lf equ 0ah ; ASCII line feed

tab equ 09h ; ASCII tab

blank equ 20h ; ASCII space character

quote equ 22h ; ASCII quote character

_TEXT segment word public 'CODE'

assume cs:_TEXT

public argc

argc proc near

push bx ; save original BX and CX

push cx ; for later

mov ax,1 ; force count >= 1

argc1: mov cx,-1 ; set flag = outside argument

argc2: inc bx ; point to next character

cmp byte ptr es:[bx],cr

je argc5 ; exit if carriage return

cmp byte ptr es:[bx],quote

je argc3 ; beginning of quoted argument

cmp byte ptr es:[bx],blank

je argc1 ; outside argument if ASCII blank

cmp byte ptr es:[bx],tab

je argc1 ; outside argument if ASCII tab

; not blank, tab, or quote,

jcxz argc2 ; jump if already inside argument

inc ax ; else found argument, count it

not cx ; set flag = inside argument

jmp argc2 ; and look at next character

argc3: inc ax ; quote found, count argument

argc4: inc bx ; point to next character

cmp byte ptr es:[bx],quote ; found end of quoted argument?

je argc1 ; yes, jump

cmp byte ptr es:[bx],cr ; found end of command line?

jne argc4 ; no, keep looking

argc5: pop cx ; restore original BX and CX

pop bx

ret ; return AX = argument count

argc endp

_TEXT ends

end

Figure 2-5.

ARGV.ASM, a routine that returns the address and length of a specified command-tail argument

title ARGV.ASM -- Return Address and Length of Argument

page 55,132

; ARGV.ASM --- Return address and length of command line argument

; or fully-qualified program name. Treats blanks and tabs

; as whitespace, carriage return as terminator, quoted

; text as a single argument.

;

; Copyright (C) 1989 Ray Duncan

;

; Call with: ES:BX = command line address

; (implicit: ES=PSP segment)

; AX = argument number (0 based)

;

; Returns: ES:BX = argument address

; AX = argument length

; (0=argument not found)

;

; Destroys: Nothing

;

; Note: if ARGV is called with AX=0 (argv[0]), and the host

; system is MS-DOS version 3.0 or later, ARGV returns ES:BX =

; address and AX = length of the fully-qualified program filename

; at the end of the program's environment block. When ARGV is

; called with AX=0 under MS-DOS versions 1.x and 2.x, it returns

; ES:BX unchanged and AX=0.

cr equ 0dh ; ASCII carriage return

lf equ 0ah ; ASCII line feed

tab equ 09h ; ASCII tab

blank equ 20h ; ASCII space character

quote equ 22h ; ASCII quote character

_TEXT segment word public 'CODE'

assume cs:_TEXT

public argv

argv proc near

push cx ; save original CX and DI

push di

or ax,ax ; is it argument 0?

jz argv12 ; yes, jump to get program name

xor ah,ah ; initialize argument counter

argv1: mov cx,-1 ; set flag = outside argument

argv2: inc bx ; point to next character

cmp byte ptr es:[bx],cr

je argv9 ; exit if carriage return

cmp byte ptr es:[bx],quote

je argv7 ; beginning of quoted argument

cmp byte ptr es:[bx],blank

je argv1 ; outside argument if ASCII blank

cmp byte ptr es:[bx],tab

je argv1 ; outside argument if ASCII tab

; if not blank, tab, or quote...

jcxz argv2 ; jump if already inside argument

inc ah ; else count arguments found

cmp ah,al ; is this the right one?

je argv4 ; yes, go find its length

not cx ; no, set flag = inside argument

jmp argv2 ; and look at next character

argv4: ; found argument, calc. length

mov ax,bx ; save param. starting address

argv5: inc bx ; point to next character

cmp byte ptr es:[bx],cr

je argv6 ; found end if carriage return

cmp byte ptr es:[bx],blank

je argv6 ; found end if ASCII blank

cmp byte ptr es:[bx],tab

jne argv5 ; found end if ASCII tab

argv6: xchg bx,ax ; set ES:BX = argument address

sub ax,bx ; and AX = argument length

jmp argv14 ; return to caller

argv7: ; start of quoted argument

inc ah ; count this argument

cmp ah,al ; is this the one we need?

je argv10 ; yes, go find its length

argv8: inc bx ; no, scan over it

cmp byte ptr es:[bx],quote ; reached trailing quote?

je argv1 ; yes, found end of argument

cmp byte ptr es:[bx],cr ; end of command line?

jne argv8 ; no, keep looking

argv9: xor ax,ax ; set AX = 0, argument not found

jmp argv14 ; return to caller

argv10: inc bx ; point to actual argument

mov ax,bx ; save its starting address

argv11: inc bx ; point to next character

cmp byte ptr es:[bx],cr

je argv6 ; found end if carriage return

cmp byte ptr es:[bx],quote

je argv6 ; found end if quote mark

jmp argv11 ; keep looking

argv12: ; special handling for parameter 0

mov ax,3000h ; check if DOS 3.0 or later

int 21h ; (force AL=0 in case DOS 1)

cmp al,3

jb argv9 ; DOS 1 or 2, return nothing

mov es,es:[2ch] ; get environment segment from PSP

xor di,di ; find the program name by

xor al,al ; first skipping over all the

mov cx,-1 ; environment variables...

cld

argv13: repne scasb ; scan for double null (can't use

scasb ; (SCASW since might be odd addr.)

jne argv13 ; loop if it was a single null

add di,2 ; skip count word in environment

mov bx,di ; save program name address

mov cx,-1 ; now find its length...

repne scasb ; scan for another null byte

not cx ; convert CX to length

dec cx

mov ax,cx ; return length in AX

argv14: ; common exit point

pop di ; restore registers

pop cx

ret ; return to caller

argv endp

_TEXT ends

end

Program TRYARGS.ASM

title TRYARGS -- Demo of ARGC.ASM and ARGV.ASM

page 55,132

; TRYARGS.ASM --- Demonstration of command line argument

; parsing by ARGC.ASM and ARGV.ASM

;

; Copyright (C) 1989 Ray Duncan

;

; Build with: MAKE TRYARGS

stdin equ 0 ; standard input handle

stdout equ 1 ; standard output handle

stderr equ 2 ; standard error handle

cmdtail equ 80h ; PSP offset of command tail

cr equ 0dh ; ASCII carriage return

lf equ 0ah ; ASCII line feed

blank equ 020h ; ASCII blank

tab equ 09h ; ASCII tab

DGROUP group _DATA,STACK

_TEXT segment word public 'CODE'

assume cs:_TEXT,ds:DGROUP,ss:STACK

extrn argc:near

extrn argv:near

main proc far

mov ax,DGROUP ; make our data segment

mov ds,ax ; addressable

mov psp,es ; save segment of PSP

mov bx,cmdtail ; ES:BX = command tail

call argc ; get number of command

; line arguments

mov pars,ax ; and save it

mov bx,offset msg1a ; convert count to ASCII

call b2dec ; for output

mov dx,offset msg1 ; display the number of

mov cx,msg1_len ; command line arguments

mov bx,stdout

mov ah,40h

int 21h

main1: mov ax,count ; display next argument

cmp ax,pars ; are we all done?

je main2 ; yes, exit

mov bx,offset msg2a ; no, convert argument number

call b2dec

mov dx,offset msg2 ; and display the number

mov cx,msg2_len

mov bx,stdout

mov ah,40h

int 21h

mov ax,count ; now get the actual argument

mov es,psp ; ES:BX = command tail

mov bx,cmdtail

call argv

push ds ; save our data segment and

push es ; display argument string

pop ds

mov dx,bx ; now DS:DX = argument addr

mov cx,ax ; and CX = argument length

mov bx,stdout

mov ah,40h

int 21h

pop ds ; restore our data segment

inc word ptr count ; go to next argument

jmp main1

main2: mov ax,4c00h ; exit to MS-DOS

int 21h

main endp

;

; B2DEC - Convert binary value 0-99 to two decimal ASCII characters

;

; Call with: AL = binary value

; BX = address to store ASCII characters

;

; Returns: Nothing

;

; Destroys: AX

;

b2dec proc near

aam ; divide AL by 10, leaving

; AH=quotient, AL=remainder

add ax,'00' ; convert to ASCII

mov [bx],ah ; store ten's digit

mov [bx+1],al ; store one's digit

ret ; return to caller

b2dec endp

_TEXT ends

_DATA segment word public 'DATA'

count dw 0 ; current command line argument

pars dw 0 ; total command line arguments

psp dw 0 ; segment base address of PSP

msg1 db cr,lf

db 'The command line contains '

msg1a db 'xx arguments'

msg1_len equ $-msg1

msg2 db cr,lf

db 'Argument '

msg2a db 'xx is: '

msg2_len equ $-msg2

_DATA ends

STACK segment para stack 'STACK'

dw 64 dup (?)

STACK ends

end main

Make file of TRYARGS.ASM

argv.obj : argv.asm

masm /Zi /T argv;

argc.obj : argc.asm

masm /Zi /T argc;

tryargs.obj : tryargs.asm

masm /Zi /T tryargs;

tryargs.exe : tryargs.obj argv.obj argc.obj

link /CODEVIEW tryargs+argv+argc;

Program TRYARGS.C

--------------------------------------

/*

TRYARGS.C - Demo of C runtime library command line argument processing

Copyright (C) 1989 Ray Duncan

*/

#include

main(int argc,char *argv[])

{

int x;

printf("\nThe command line contains %d arguments", argc);

for (x=0; x ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download

To fulfill the demand for quickly locating and searching documents.

It is intelligent file search solution for home and business.

Literature Lottery

Related searches