Annotation of os2sdk/startup/os2/stdenvp.asm, revision 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.