71 lines
2.1 KiB
ArmAsm
71 lines
2.1 KiB
ArmAsm
|
/* This routine potentially increases the stack size at runtime based on
|
||
|
the _stklen variable. Only used by DPMI code.
|
||
|
Copyright (c) 1993 C. Sandmann
|
||
|
Environment: called by crt0.s (and gcrt0.s)
|
||
|
EAX, EBX, EBP, EDI, ESI disposable (cleared on return) */
|
||
|
|
||
|
.text
|
||
|
.globl __setstack
|
||
|
__setstack:
|
||
|
movl %esp,%eax
|
||
|
andl $0xc0000000,%eax /* clear all except upper bits */
|
||
|
jne ok_stack /* obviously not DPMI! */
|
||
|
movw %ss,%ax
|
||
|
lsll %eax,%ebx /* stack segment limit */
|
||
|
movl %esp,%eax /* current location */
|
||
|
subl %ebx,%eax /* Free stack */
|
||
|
cmpl %eax,__stklen
|
||
|
jb ok_stack
|
||
|
|
||
|
/* Not enough stack. Call sbrk() to get a new area. Copy current ESP + 20
|
||
|
to end of new area (3 args + our stack). Change ESP to new area. Set new
|
||
|
limit to start of new area using DPMI services. */
|
||
|
|
||
|
pushl __stklen
|
||
|
call _sbrk /* eax = got memory base */
|
||
|
popl %ebx /* remove _stklen */
|
||
|
cmpl $0xffffffff,%eax /* if eax = -1 failure */
|
||
|
je badstack
|
||
|
addl %eax,%ebx /* ebx now is end of new stack area */
|
||
|
andl $0xfffffff0,%ebx /* 16 byte alignment */
|
||
|
addl $0xfff,%eax /* make stack base page aligned */
|
||
|
andl $0xfffff000,%eax /* 4096 byte alignment */
|
||
|
|
||
|
/* Now copy old stack to new stack. We only need our part + 4 words, 3 for
|
||
|
the parameters to pass to main, one for our return EIP (4 extra safety) */
|
||
|
movl %esp, %esi /* Source is current stack */
|
||
|
subl $0x20, %ebx /* 8 longwords */
|
||
|
movl %ebx, %edi /* Destination is new stack */
|
||
|
movl $8,%ecx
|
||
|
rep
|
||
|
movsl
|
||
|
|
||
|
/* New stack in place. Change ESP to point to it. Assumes new stack is
|
||
|
higher in memory so we don't get caught by limit. Change limit using
|
||
|
DPMI services. */
|
||
|
|
||
|
movl %ebx,%esp /* Switch to new stack */
|
||
|
subl $1,%eax /* Low 12 bits all 1s */
|
||
|
pushl %eax /* Easiest way to move long to words */
|
||
|
popw %dx
|
||
|
popw %cx
|
||
|
movl $8,%eax /* DPMI function Set Segment Limit */
|
||
|
movw %ss,%bx /* Selector */
|
||
|
int $0x31 /* Do service */
|
||
|
|
||
|
xor %ecx,%ecx /* Clean up */
|
||
|
xor %edx,%edx /* Clean up */
|
||
|
|
||
|
ok_stack:
|
||
|
ret /* What we have is already bigger */
|
||
|
|
||
|
badstack:
|
||
|
movl $0x4c01,%eax
|
||
|
int $0x21
|
||
|
jmp badstack
|
||
|
|
||
|
.data
|
||
|
.globl __stklen
|
||
|
.comm __stklen,4
|
||
|
|