[9] | 1 | ! This is the C run-time start-off routine. It's job is to take the
|
---|
| 2 | ! arguments as put on the stack by EXEC, and to parse them and set them up the
|
---|
| 3 | ! way _main expects them.
|
---|
| 4 | ! It also initializes _environ when this variable isn't defined by the
|
---|
| 5 | ! programmer. The detection of whether _environ belong to us is rather
|
---|
| 6 | ! simplistic. We simply check for some magic value, but there is no other
|
---|
| 7 | ! way.
|
---|
| 8 |
|
---|
| 9 | .sect .text; .sect .rom; .sect .data; .sect .bss
|
---|
| 10 |
|
---|
| 11 | .define begtext, begdata, begbss
|
---|
| 12 | .sect .text
|
---|
| 13 | begtext:
|
---|
| 14 | .sect .rom
|
---|
| 15 | begrom:
|
---|
| 16 | .sect .data
|
---|
| 17 | begdata:
|
---|
| 18 | .sect .bss
|
---|
| 19 | begbss:
|
---|
| 20 |
|
---|
| 21 | .define crtso, __penviron, __penvp, __fpu_present
|
---|
| 22 | .extern _main, _exit
|
---|
| 23 | .sect .text
|
---|
| 24 | crtso:
|
---|
| 25 | xor ebp, ebp ! clear for backtrace of core files
|
---|
| 26 | mov eax, (esp) ! argc
|
---|
| 27 | lea edx, 4(esp) ! argv
|
---|
| 28 | lea ecx, 8(esp)(eax*4) ! envp
|
---|
| 29 |
|
---|
| 30 | ! Test if environ is in the initialized data area and is set to our
|
---|
| 31 | ! magic number. If so then it is not redefined by the user.
|
---|
| 32 | mov ebx, _environ
|
---|
| 33 | cmp ebx, __edata ! within initialized data?
|
---|
| 34 | jae 0f
|
---|
| 35 | testb bl, 3 ! aligned?
|
---|
| 36 | jnz 0f
|
---|
| 37 | cmp (ebx), 0x53535353 ! is it our _environ?
|
---|
| 38 | jne 0f
|
---|
| 39 | mov (__penviron), ebx ! _penviron = &environ;
|
---|
| 40 | 0: mov ebx, (__penviron)
|
---|
| 41 | mov (ebx), ecx ! *_penviron = envp;
|
---|
| 42 |
|
---|
| 43 | push ecx ! push envp
|
---|
| 44 | push edx ! push argv
|
---|
| 45 | push eax ! push argc
|
---|
| 46 |
|
---|
| 47 | ! Test the EM bit of the MSW to determine if an FPU is present and
|
---|
| 48 | ! set __fpu_present if one is found.
|
---|
| 49 | smsw ax
|
---|
| 50 | testb al, 0x4 ! EM bit in MSW
|
---|
| 51 | setz (__fpu_present) ! True if not set
|
---|
| 52 |
|
---|
| 53 | call _main ! main(argc, argv, envp)
|
---|
| 54 |
|
---|
| 55 | push eax ! push exit status
|
---|
| 56 | call _exit
|
---|
| 57 |
|
---|
| 58 | hlt ! force a trap if exit fails
|
---|
| 59 |
|
---|
| 60 | .sect .rom
|
---|
| 61 | .data4 0 ! Separate I&D: *NULL == 0
|
---|
| 62 | ! Also keeps the first string in the
|
---|
| 63 | ! program from appearing at location 0!
|
---|
| 64 | .sect .data
|
---|
| 65 | __penviron:
|
---|
| 66 | .data4 __penvp ! Pointer to environ, or hidden pointer
|
---|
| 67 |
|
---|
| 68 | .sect .bss
|
---|
| 69 | .comm __penvp, 4 ! Hidden environment vector
|
---|
| 70 | .comm __fpu_present, 4 ! FPU present flag
|
---|
| 71 |
|
---|
| 72 | .extern endtext ! Force loading of end labels.
|
---|