|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.