_ARGUMENTS AND AUTOMATIC VARIABLES IN ASSEMBLY LANGUAGE_
by 
Raymond Moon

LISTING ONE

 1    page 60,132
 2    title FILE_LENGTH - Determine File Length In Bytes
 3    name FILE_LEN
 4
 5  comment @
 6    FILE_LENGTH()                                 V 1.00
 7  -------------------------------------------------------
 8  NAME
 9    file_length()         Determine file length in bytes
 10
 11  SYNOPSIS
 12    length = file_length(filename, attribute);
 13    long          length;         length of file in bytes
 14    char          *filename;      path\filename.ext
 15    unsigned int  attribute;      file attribute used
 16                                   in search
 17
 18  DESCRIPTION
 19    This function uses DOS function 4eh, Find First
 20    File, to return with the filelength.  So that this
 21    function does not corrupt the current Data Transfer
 22    Area, DTA, this function moves the DTA to its own
 23    automatic variable area.  If the file is not found,
 24    -1L is returned.
 25
 26    This function allows any kind of file to be found by
 27    specifying the file attribute.  The following #define
 28    statements can be used to define the various file
 29    attributes:
 30
 31    #define NORM          0x00    /* Normal file    */
 32    #define RO            0x01    /* Read-only file */
 33    #define HID           0x02    /* Hidden file    */
 34    #define SYS           0x04    /* System file    */
 35    #define VOL_ID        0x08    /* Volume ID      */
 36    #define SUBDIR        0x10    /* Subdirectory   */
 37    #define ARCH          0x20    /* Archive file   */
 38
 39    The bit or operator, |, can be used to combine
 40    several attributes.  For example:
 41
 42    length = file_length("filename.ext", RO|HID|SYS);
 43
 44    All normal, read-only, hidden, and system files will
 45    be searched for a match to "filename.ext."
 46
 47    This procedure was assembled using MICROSOFT MASM
 48    V5.0 with the switches, /v /ml /z, set.
 49
 50  CAUTION
 51    None.
 52
 53  RETURNS
 54    File length as a long.  -1L signifies an error.
 55
 56  AUTHOR
 57    Raymond Moon - 18 Nov 87
 58
 59    Copyright (c) 1987, MoonWare
 60    ALL RIGHTS RESERVED
 61
 62  HISTORY
 63    Version - Date        Remarks
 64    1.00  - 18 Nov 87     - Orginal
 65
 66    @
 67
 68  ;----------------------------
 69  ;  Define the segments for the memory model so that
 70  ;  they can link with Microsoft C.
 71
 72  _TEXT   segment byte public 'CODE'
 73  _TEXT   ends
 74
 75  _DATA   segment word    public  'DATA'
 76  _DATA   ends
 77
 78  CONST   segment word    public  'CONST'
 79  CONST   ends
 80
 81  _BSS    segment word    public  'BSS'
 82  _BSS    ends
 83
 84  DGROUP  group   _DATA, CONST, _BSS
 85
 86  ;----------------------------
 87  ;  Define the assume directive so MASM knows to what
 88  ;  the segment registers point
 89
 90  assume  cs:_TEXT, ds:DGROUP, ss:DGROUP, es:DGROUP
 91
 92  ;----------------------------
 93  ;  Define the structures for passed parameters and
 94  ;  automatic variables.
 95
 96  PARMS    struc
 97           dw     2 dup (?)
 98  FILENAME dw     ?
 99  ATTR     dw     ?
100  PARMS    ends
101
102  ;----------------------------
103  ;  _AUTO structure contains the following variables:
104  ;  OLD_DTA      Saved address of old DTA
105  ;  NEW_DTA      Start of NEW_DTA, this first field is
106  ;                reserved for subseqent Find Next File
107  ;  F_ATTR       Attribute found
108  ;  F_TIME       Time file was last written
109  ;  F_DATE       Date file was last written
110  ;  F_LENGTH     Double word file length
111  ;  F_NAME       Found filename.ext
112
113  _AUTO    struc
114  OLD_DTA  dd     ?
115  NEW_DTA  db     21 dup (?)
116  F_ATTR   db     ?
117  F_TIME   dw     ?
118  F_DATE   dw     ?
119  F_LENGTH dd     ?
120  F_NAME   db     13 dup (?)
121  _AUTO    ends
122
123  ;----------------------------
124  ;  Define structures for addressing trhe offset and
125  ;  segment portions of doubleword pointers and the
126  ;  least and most significant words of long intergers.
127
128  DOUBLEWORD_PTR  struc
129  OFF     dw      ?
130  SEGMT   dw      ?
131  DOUBLEWORD_PTR  ends
132
133  LONG_INT        struc
134  LSW     dw      ?
135  MSW     dw      ?
136  LONG_INT        ends
137
138  ;----------------------------
139  ;  Start the Code Segment.
140
141  _TEXT   segment
142
143  _FILE_LENGTH    proc    near
144
145          public  _FILE_LENGTH
146
147  ;----------------------------
148  ;  Standard entry logic.  Save calling BP.  Set up new
149  ;  BP.  Define automatic variable addressing base,
150  ;  AUTO.  Save segment registers are saved as DS and
151  ;  ES are used.
152
153          push    bp
154          mov     bp,sp
155          sub     sp, size _AUTO
156          AUTO    equ [bp - size _AUTO]
157          push    ds
158          push    es
159
160  ;----------------------------
161  ;  Get and save current DTA address in OLD_DTA.  Use
162  ;  DOS service 2fh.  The address is returned in ES:BX.
163
164          mov     ah,2fh
165          int     21h
166          mov     AUTO.OLD_DTA.OFF,bx
167          mov     AUTO.OLD_DTA.SEGMT,es
168
169  ;----------------------------
170  ;  Set up NEW_DTA as the current DTA.  Use DOS service
171  ;  1ah.  DS = SS assumed.
172
173          mov     ah,1ah
174          lea     dx,AUTO.NEW_DTA
175          int     21h
176
177  ;----------------------------
178  ;  Set up for File First Find, Service 4eh.
179  ;  CX = Search attribute
180  ;  DS:DX => ASCIIZ string, d:path\filename.ext
181
182          mov     ah,4eh
183          mov     cx,[bp].ATTR
184          mov     dx,[bp].FILENAME
185          int     21h
186
187  ;----------------------------
188  ;  Check for Carry Flag set as that indicates that the
189  ;  file was not found.  If so, put -1L in F_LENGH so
190  ;  -1L is returned as file length.
191
192          jnc     FL1
193          mov     ax,-1
194          mov     AUTO.F_LENGTH.LSW,ax
195          mov     AUTO.F_LENGTH.MSW,ax
196
197  ;----------------------------
198  ;  Restore old DTA, service 1ah.
199  ;  DS:DX => old DTA.
200
201  FL1:    mov     ah,1ah
202          mov     dx,AUTO.OLD_DTA.OFF
203          mov     ds,AUTO.OLD_DTA.SEGMT
204          int     21h
205
206  ;----------------------------
207  ;  Set up AX:DX to return file length.
208
209          mov     ax,AUTO.F_LENGTH.LSW
210          mov     dx,AUTO.F_LENGTH.MSW
211
212  ;----------------------------
213  ;  Exit logic.  Restore segment registers.  Remove any
214  ;  automatic variables.  Restore calling BP.
215
216          pop     es
217          pop     ds
218          mov     sp,bp
219          pop     bp
220          ret
221
222  _FILE_LENGTH    endp
223
224  _TEXT   ends
225
226          end




Example 1: Definition of strncpy()

    char *strncpy(string1, string2, n);
    char *string1;   pointer to the first string
    char *string2;   pointer to the second string
    unsigned int n;  number of characters to be
                     copied


Example 2: needs caption


 PARMS struc      ; Passed arg addressing struc
       dw   2 dup(?) ; Saved IP and bp registers
    string1 dw    ?  ; Pointer to 1st string
    string2 dw    ?  ; Pointer to 2nd string
    N       dw    ?  ; # char to copy
    PARMS ends



Example 3:  Automatic variable structure


    _AUTO    struc    ; Auto var addressing struc
    INT_1    dw   ?   ; 1st automatic variable
    INT_2    dw   ?   ; 2nd automatic variable
    INT_3    dw   ?   ; 3rd automatic variable
    _AUTO ends


Example 4: Standard entry code 

    push bp        ; Save the called bp
    mov  bp,sp     ; Initialize new frame pointer
    sub  sp,size _AUTO
                   ; Make room for auto vars
    AUTO equ [bp - size _AUTO]
                   ; Auto var addressing base

Example 5: #defines for file attributes to be used with file_length()


    #define NORM     0x00     /* Normal file    */
    #define RO       0x01     /* Read-only file */
    #define HID      0x02     /* Hidden file    */
    #define SYS      0x04     /* System file    */
    #define VOL_ID   0x08     /* Volume ID      */
    #define SUBDIR   0x10     /* Subdirectory   */
    #define ARCH     0x20     /* Archive file   */




-30-
