Annotation of os2sdk/startup/os2/stdenvp.asm, revision 1.1.1.1

1.1       root        1:        TITLE   stdenvp - OS/2 standard _setenvp routine
                      2: ;***
                      3: ;5stdenvp.asm - OS/2 standard _setenvp routine
                      4: ;
                      5: ;      Copyright (c) 1985-1987, Microsoft Corporation.  All rights reserved.
                      6: ;
                      7: ;Purpose:
                      8: ;      This module is called by the C start-up routine to set up "environ".
                      9: ;      It copies the environment strings into the heap/stack, preceded by a
                     10: ;      null-terminated array of pointers to those strings.
                     11: ;      The global symbol "_environ" is set to point to this array.
                     12: ;
                     13: ;*******************************************************************************
                     14: 
                     15: include        version.inc
                     16:        .xlist
                     17: include        cmacros.inc
                     18: include        msdos.inc
                     19:        .list
                     20: 
                     21: sBegin data
                     22: assumes        ds,data
                     23: 
                     24: externDP environ               ; environment pointer
                     25: externW        _aenvseg                ; Environment segment
                     26: externB        _acfinfo                ; C_FILE_INFO string
                     27: 
                     28: staticCP retadr,0              ; return address
                     29: 
                     30: sEnd   data
                     31: 
                     32: 
                     33: sBegin code
                     34: 
                     35: externNP _stdalloc             ; routine to allocate heap/stack space
                     36: externNP _amsg_exit            ; Routine for error messages.
                     37: 
                     38: assumes        ds,data
                     39: assumes        cs,code
                     40: 
                     41: page
                     42: ;***
                     43: ;_stdenvp - set up "envp" for C programs
                     44: ;
                     45: ;Purpose:
                     46: ;      Reads the environment and build the envp array for C programs.
                     47: ;
                     48: ;Entry:
                     49: ;      The environment strings occur at the beginning of the segment.
                     50: ;      The list of environment strings is terminated by an extra null
                     51: ;      byte.  Thus two null bytes in a row indicate the end of the
                     52: ;      last environment string and the end of the environment, resp.
                     53: ;
                     54: ;Exit:
                     55: ;      "environ" points to a null-terminated list of pointers to ASCIZ
                     56: ;      strings, each of which is of the form "VAR=VALUE".  The strings
                     57: ;      are copied from the environment segment into space allocated on
                     58: ;      the heap/stack.  The list of pointers is also located on there.
                     59: ;
                     60: ;Uses:
                     61: ;      Locks the environment segment before use, and unlocks afterward
                     62: ;      Allocates space on the heap/stack for the environment strings
                     63: ;      and a list of pointers to them.
                     64: ;
                     65: ;      All registers except DS, SS, and BP are modified
                     66: ;      Note especially that SI and DI are NOT preserved!
                     67: ;
                     68: ;Exceptions:
                     69: ;
                     70: ;*******************************************************************************
                     71: 
                     72: labelP <PUBLIC,_setenvp>
                     73: 
                     74:        pop     word ptr [retadr] ; get return address (offset)
                     75: 
                     76: if     sizeC
                     77:        pop     word ptr [retadr+2] ; get return address (segment)
                     78: endif
                     79: 
                     80: assumes        ds,data
                     81: 
                     82:        mov     es,_aenvseg     ; point to environment segment
                     83:        assumes es,nothing
                     84: 
                     85: ;      setup envp vector and move environment to heap/stack
                     86: ;
                     87: ;      ES = environment segment, DS = SS = DGROUP
                     88: 
                     89:        xor     ax,ax           ; ax = 0 (search byte)
                     90:        xor     si,si           ; si = 0 (envp count)
                     91:        xor     di,di           ; di = 0 (initial offset)
                     92:        mov     cx,-1           ; cx = ffff (infinite count)
                     93: 
                     94: ;*
                     95: ;      Scan past the list of environment strings
                     96: ;      Stop on a double null byte
                     97: ;      SI will count the number of environment strings
                     98: ;      DI will count the number of bytes the strings occupy
                     99: ;
                    100:        cmp     ax,ES:[di]
                    101:        je      noenv
                    102: scanenv:
                    103:        repnz   scasb
                    104:        inc     si              ; si = envp count
                    105:        scasb
                    106:        jnz     scanenv
                    107:                                ; di = count of string bytes
                    108: noenv:
                    109:        inc     si              ; si = envp count + 1
                    110:        mov     ax,di           ; ax = envlen
                    111:        inc     ax
                    112:        and     al,not 1        ; round up to even
                    113:        mov     di,si           ; di = argument count
                    114:        shl     si,1            ; argument count*2
                    115: if     sizeD
                    116:        shl     si,1            ; argument count*2
                    117: endif
                    118: ;
                    119: ;      Need to allocate space for environment strings on the heap/stack
                    120: ;      Number bytes needed = 2[4] * (Number of Strings + 1)
                    121: ;                              + Number of Bytes in Strings
                    122: ;
                    123:        add     ax,si           ; ax = space to allocate
                    124: ;
                    125: ; _stdalloc allocates (AX) bytes from the heap or the stack
                    126: ;
                    127:        call    _stdalloc       ; preserves bp, si, di
                    128:        jnc     env_ok
                    129: 
                    130:        mov     ax,9            ;Memory error.
                    131:        jmp     _amsg_exit
                    132: 
                    133: env_ok:
                    134:        mov     word ptr [environ],ax ; save envp[]
                    135: 
                    136: if     sizeD
                    137:        mov     word ptr [environ+2],ss ; segment address for large model
                    138: endif
                    139: 
                    140: envnext:
                    141:        mov     cx,di           ; cx = envcnt
                    142:        mov     di,ax
                    143:        add     di,si           ; di = env strings area
                    144:        mov     bx,ax           ; bx = env pointers area
                    145: ;
                    146: ; BX points to where envp[0], envp[1], ... will be stored
                    147: ; DI points to where *envp[0], *envp[1], ... will be stored
                    148: ;
                    149:        push    es
                    150:        pop     ds
                    151:        xor     si,si           ; ds:si = environment table
                    152: 
                    153:        push    ss
                    154:        pop     es              ; es:di = env dest
                    155: 
                    156: assumes        es,data
                    157: assumes        ds,nothing
                    158: 
                    159:        dec     cx              ; adjust for the last entry of 0000
                    160:        jcxz    envdone         ;   done - no environment
                    161: 
                    162: ;
                    163: ; Copy each null-terminated environment string from DS:SI to ES:DI
                    164: ; Add the address of each string to the list at ES:BX
                    165: ; Skip the "_C_FILE_INFO" entry by not putting it in the pointer list
                    166: ;
                    167: envloop:
                    168:        mov     ax,[si]
                    169:        cmp     ax,word ptr [_acfinfo]
                    170:        jne     not_cfi         ; don't save pointer if '_C'...
                    171: ;
                    172: may_be_cfi:
                    173:        push    cx
                    174:        push    si
                    175:        push    di              ; preserve context
                    176: 
                    177:        mov     di,dataOFFSET _acfinfo ; ES:DI points to C_FILE_INFO string
                    178:        mov     cx,6            ; length of that string in words
                    179:        repe    cmpsw           ; cmpsw is faster than cmpsb
                    180: 
                    181:        pop     di
                    182:        pop     si
                    183:        pop     cx              ; restore context
                    184:        je      envstr          ; if match, skip this pointer
                    185: ;
                    186: not_cfi:
                    187:        mov     es:[bx],di      ; save pointer to start of string
                    188: if     sizeD
                    189:        mov     es:[bx+2],ss    ; segment address for large model
                    190:        add     bx,4
                    191: else
                    192:        inc     bx
                    193:        inc     bx
                    194: endif
                    195: 
                    196: envstr:
                    197:        lodsb
                    198:        stosb
                    199:        or      al,al
                    200:        jnz     envstr          ; keep copying string
                    201: 
                    202:        loop    envloop         ; more strings to copy
                    203: 
                    204: ;
                    205: ;      DS:SI   points after the environment strings
                    206: ;
                    207: envdone:
                    208:        mov     es:[bx],cx      ; zero terminate envp table
                    209: if     sizeD
                    210:        mov     es:[bx+2],cx    ; extra zero for large model
                    211: endif
                    212: 
                    213:        push    ss
                    214:        pop     ds
                    215:        push    ss
                    216:        pop     es              ; ES = DS = DGROUP
                    217: 
                    218: assumes        ds,data
                    219: 
                    220:        jmp     [retadr]
                    221: 
                    222: sEnd   code
                    223: 
                    224:        end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.