News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

how can i access command line arguments masm program

Started by hellfix, June 11, 2012, 02:07:09 PM

Previous topic - Next topic

hellfix

how can i access command line arguments and used them as parameters in my program. im trying couple examples but they get complicated can someone show me a small program that highlights instructions accessing these arguments.

im using a book example that overlays the program segment prefix. the program does not make use of command line parameters the question im asking is how can i print the parameters in the program or use them efficiently.

Here the program from a book example

Page 62,132
Title skeleton assembly program
page

;define stack sement
stack segment para stack 'stack'
      db    64 dup('stack  ')
stack ends

;This is segement that will overlay the offcial psp made by dos
;the program dose not make use of this how can i 
;define program segment prefix

prefix segment AT 0
             org 80
cmdcnt   db      ?              ;command line count
cmdstr   db  80 dup(?)     ;command line string
prefix ends

;define data segementt
dseg   segment para public 'data'
aprefix  dw        0
logo     db        'skeleton program executed',13,10,'$'

dseg   ends

;define code segment
cseg    segment para public 'code'

start proc far
     assume cs:cseg,ss:stack,es:prefix
     
     mov ax,dseg              ;address of data segment
     mov ds,ax                  ;now points to data
     assume ds:dseg        ;Tell the assembler where the data segement is
     mov aprefix,es           ;save prefix segment
               ;
    ;We know where all the segments are pointting to
                              ;
    ;scan input parameter line
    mov di,offset cmdstr         ;get the address of the string
    mov ch,0                           ;zero the upper bits
    mov cl,cmdcnt                   ;tell me if there are any parameters
    cmp cx,0                           ;next instruction following this one will jump if yes
    jnz sc                                ;the instruction above sets the z flag if not then jump
    jmp scanx

   ;set up default parameters here

sc: mov al,es:[di]                  ;get ist parameter char
    and al,0dh                        ;convert to upper case
   
   ;handle parameters here

   scn:inc di
   
    ;i dont know what im doing here trying to print a character at a time
    ;print command line parameters
    mov dl,al
    mov al,2 ;display character
    int 21h

    loop sc
scanx:nop

;start of main program
    call clrscn
    mov dx,offset logo
    call print

;return to dos
done:mov ax,aprefix
     push ax
     sub ax,ax
     push ax
     ret

   start endp
   
clrscn proc
     push ax
     mov ax,2
     int 10h
     pop ax
     ret
clrscn endp

print proc
     push ax
     mov ah,9
     int 21h
     pop ax
     ret
print endp

cseg ends
     end start

dedndave

you are writing a 16-bit EXE program
the PSP segment is passed to the program at startup in DS and in ES
normally, when you start up, you load the data segment into the DS register
if you may want to access the PSP later in the program, it is a good idea to save the PSP segment value
Start:  mov     ax,@data
        mov     dx,ax

;now, the DS register points to our data segment
;this is a good time to store the value in ES into a variable in .DATA?

        mov     PspSeg,es


once you have that, the command line tail length is at PSP:0080h
it is a byte that tells you the length of the command line (127 max in DOS)
at PSP:0081h is the beginning of the command line tail

hellfix

Im still kinda lost. the program saves the segment prefix but it reads the command
line argument a character at time how can i print the info i tried function character display

mov dl, 'c'
mov ah,2
int 21h

im a newbie at this

hellfix

i get the command line string is at 82 but the program saves the command line arguments at 82 how can i print to the screen i keep getting this part wrong

jj2007

.model tiny

.code
org 100h
start:
mov ah, 09h ; write string to STDOUT
mov dx, 82h ; get command line
int 21h ; show it... ;-)
ret
end start

FORTRANS

Hi,

   If you use the program jj2007 wrote, make sure the
last character of the command line is a dollar sign '$'.

   You do not want to declare:


prefix segment AT 0


That points to a segment at 0000:0000, not the PSP.  You are
storing ES and can use that value to access initialize DS or just use
an ES override to access the command line.  Maybe something like
the following:


    mov aprefix,es           ;save prefix segment
               ;
    ;We know where all the segments are pointting to
                              ;
    ;scan input parameter line
    mov di,81                          ;get the address of the string
    mov ch,0                           ;zero the upper bits
    mov cl,ES:[80]                     ;tell me if there are any parameters
    cmp cx,0                           ;next instruction following this one will jump if yes
    jnz sc                             ;the instruction above sets the z flag if not then jump
    jmp scanx


Regards,

Steve N.

dedndave

as i mentioned before, for an EXE, the PSP is passed to the program in DS and in CS
for TINY model programs, CS = DS = ES = SS = PSP
so, it's a little simpler than it is for EXE's
see attached...

hellfix

Thanks for your help guys i finally got it to work but it dosent look good there are unwanted characters in the string for some reason appear on screen mayby i didnt fully do it properly but it works. Thanks again

TITLE SAMPLE - SHOWS DOS CALLING CONVENTIONS FOR .COM FILES
COMSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG

ORG 80H             
CMDCNT DB ?          ;COMMAND LINE COUNT
CMDSTR DB 80 DUP(?)  ;COMMAND LINE BUFFER
ORG 100H
   
START PROC FAR
       JMP ENTRY     ;JUMP PASS DATA
;--------------------------------------------
LOGO DB  'SAMPLE PROGRAM EXECUTED',13,10,'$'
data db  15 dup(?),'$'
;--------------------------------------------

;SCAN INPUT PARAMETER LINE

ENTRY:  MOV SI,OFFSET CMDSTR ;STRING
        MOV DI,OFFSET data
       
   MOV CH,0
   MOV CL,ES:[80]      ;PARAMETER COUNT by variable CMDCNT
   CMP CX,0
   JNZ SCAN0           ;YES - PROCESS COMMAND LINE PARAMETERS
   JMP SCANX           ;NO - PARAMETERS
   
SCAN0:   MOV al,[SI]
                mov [di],al
   
   inc si
   inc di             ;INCREMENT STRING
   LOOP SCAN0
   
SCANX:  NOP

;START OF MAIN PROGRAM
         
CALL IAMHERE          ;DISPLAY MESSAGE

;RETURN TO DOS
DONE: PUSH DS
      MOV AX,0
      PUSH AX
      RET
START ENDP

;MESSAGE
IAMHERE PROC
        PUSH AX
   PUSH DX

   MOV AH,9
   MOV DX, OFFSET LOGO
   INT 21H
   
   ;----print command line string
   mov ah,9
   mov dx,offset data
   int 21h

   POP DX
   POP AX
IAMHERE ENDP

COMSEG ENDS

END START

MichaelW

If you are intend to display the command tail with Function 9, you need to scan it for the terminating CR (ASCII character 13) and replace that with "$". IIRC the normal practice is to ignore the length in the leading byte and just scan for the end.
Well Microsoft, here's another nice mess you've gotten us into.

FORTRANS

Hi,

   Since you changed back from an *.EXE program to a *.COM
program, you can use the names and avoid the ES override.
Those are needed in an *.EXE program as the PSP is a bit
harder to access.

   An alternate method is output the characters one by one.
You can use the DOS console output function or the video
BIOS Int 10H function 0EH.  Something like:


SCAN0:   MOV al,[SI]
                mov [di],al

        MOV     DL,AL   ; Put character into DL register.
        MOV     AH,2    ; DOS function 2 is Console Output (of a character).
        INT     21H     ; Execute DOS functions.

   inc si
   inc di             ;INCREMENT STRING
   LOOP SCAN0


   Or;


        MOV     AH,0EH  ; Write Teletype
        INT     10H     ; Video Int.


   Or use the character count in an index or base register
to overwrite the CR in the command line with a dollar sign
'$'.

HTH,

Steve