home *** CD-ROM | disk | FTP | other *** search
- ;
- ; alloca.8 begins
- ; source for a86 assembler
- ; released into the public domain with the restriction that the
- ; acknowledgement below be preserved:
- ; ... This alloca() for Turbo C is by Alexander Pruss ...
- ;
- ; Assemble via:
- ; A86 +oc =__<MODEL-IDENTIFIER>__ alloca.8
- ; Note that the HUGE alloca = LARGE alloca and that TINY alloca = SMALL alloca
- ;
- #if __MEDIUM__
- L_CODE = 1
- #elseif __COMPACT__
- L_DATA = 1
- #elseif __LARGE__
- L_DATA = 1
- L_CODE = 1
- #elseif __HUGE__
- L_DATA = 1
- L_CODE = 1
- #endif
-
- #if L_CODE
- ALLOCA_TEXT segment byte public 'CODE'
- #else
- TEXT segment byte public 'CODE'
- #endif
-
- @alloca_buffer dw ?
-
- public __alloca
- ;; void *_alloca(unsigned size) ;;
- __alloca:
- pop bx ; Return address
- #if L_CODE
- pop es ; into [ES:]BX
- #endif
- pop cx ; Data size. (Argument to alloca)
-
- pop dx ; Store some
- pop ax
- #if L_DATA
- pop cs:@alloca_buffer ; data from caller's stack
- push cs:@alloca_buffer ; (DS,SI,DI--some may not be necessary)
- #endif ; DS unnecessary for small data models
- push ax ; we put it back after reading
- push dx
- inc cx ; Round CX to even. (SP must be even,
- ; else performance degrades)
- shr cx,1
- shl cx,1
- sub sp,cx ; Allocate the space
-
- #if L_DATA
- push cs:@alloca_buffer ; make a copy of the possible data
- #endif
- push ax ; (DS,SI,DI) on the caller's stack
- push dx
-
- mov ax,sp ; Return value.
- #if L_DATA
- add ax,8 ; remember we put 3 words on the stack
- ; and the stack points to a free word
- #else
- add ax,6 ; 2 words for small data models only
- #endif
- push cx ; put the size back on the stack
- #if L_CODE
- push es ; high order return address
- #endif
- push bx ; low order return address
- #if L_DATA
- mov dx,ss ; high order return value
- #endif
- #if L_CODE
- retf ; out we go!
- #else
- ret
- #endif
-
- ALLOCA_TEXT ends
- end
-