1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
; $Id: alloca.asm,v 1.1.1.1 2000/06/27 01:47:58 amura Exp $
;-------------------------------------------------------------
; alloca.asm: void * alloca(int) for Turbo-C 2.0
;
; CAUTION:
; * Standard stack frame is required in caller function
; You had better use -k (Standard stack frame) option.
;
; $Header: /var/cvsroot/ng/sys/msdos/alloca.asm,v 1.1.1.1 2000/06/27 01:47:58 amura Exp $
;-------------------------------------------------------------
; $Log: alloca.asm,v $
; Revision 1.1.1.1 2000/06/27 01:47:58 amura
; import to CVS
;
include rules.asi
Header@
CSeg@
PubProc@ alloca, __CDECL__
pop cx ;retrun address
if LPROG
pop dx ;;return segment
endif
pop ax ;argument
or ax, ax ;test if 0
jz eret ;no allocation required
inc ax ;
and al, 0FEh ;force Even
mov bx, sp ;caller function stack position
sub bx, ax ;get space
jc eret ;under flow!
if LDATA
ExtSym@ _stklen, word, __CDECL__
cmp bx, 12 ;;12 bytes use later
jc eret ;;
; ifdef __HUGE__ ;; old!
; mov ax, seg _stklen@
; mov es, ax ;;
; mov ax, word ptr es:_stklen@
; else ;;
mov ax, word ptr DGROUP:_stklen@
cmp ax, bx ;;
jb eret ;;
else ;;
ExtSym@ __brklvl, word, __CDECL__
mov ax, word ptr DGROUP:__brklvl@
add ax, 10 ;; 12 bytes usr later
cmp ax, bx ;;
jnc eret ;;
endif ;;
mov ax, bx ; <- pointer to allocated memory
xchg sp, bx ; sp <- new pos / bx <- old pos
push ss:[bx+4] ; for safe..
push ss:[bx+2] ; for DI (may be)
push ss:[bx+0] ; for SI (may be)
if LPROG
mov bx, dx ;;save return segment
endif
if LDATA
mov dx, ss ;;allocated mem segment address
endif ;;
goback: push ax ; restore argument space
if LPROG ;;
push bx ;;restor return segment
endif ;;
push cx ; restore return address
ret ; bye-be
eret: xor ax, ax ; NULL
if LPROG ;;
mov bx, dx ;;save return segment
endif ;;
if LDATA ;;
mov dx, ax ;;NULL
endif ;;
jmp short goback ;
EndProc@ alloca, __CDECL__
CSegEnd@
end
|