//wmincrt/startup.asm |
---|
File deleted |
//wmincrt/tests/stkchk/build.bat |
---|
File deleted |
\ No newline at end of file |
//wmincrt/tests/stkchk/stkchk.c |
---|
File deleted |
//wmincrt/tests/hello/hello.c |
---|
File deleted |
//wmincrt/tests/hello/build.bat |
---|
File deleted |
//wmincrt/tags/20231113/startup.asm |
---|
0,0 → 1,157 |
; WMINICRT - minimal runtime for (Open) Watcom C to generate DOS .COM files |
; |
; The default behaviour of the runtime is: |
; - sets up a stack of 400H bytes |
; - releases additional memory beyond stack to DOS |
; - panics on initialization, if not enough memory for stack size |
; - panics if running out of stack during execution |
; |
; WASM definitions: |
; STACKSIZE=<value> define stack size other than 400h |
; NOSTACKCHECK do not assemble __STK function |
; STACKSTAT remember the minimum SP, maintained by __STK__ |
; and exported via _stack_low_. |
; |
; To build an executable without build- and linker scripts run: |
; wasm startup.asm |
; wcc -0 -bt=dos -ms -os -zl your_c_file.c |
; wlink system dos com file startup,your_c_file |
; To change the stack size, add -DSTACKSIZE=<value> to the wasm call |
; |
; To compile without stack checking: |
; a) compile this startup file with wasm -DNOSTACKCHECK startup.asm |
; b) call the C compiler with -s flag |
; |
; To build a debug version of your program: |
; wasm -d1 startup.asm |
; wcc -bt=dos -ms -d2 -zl your_c_file.c |
; wlink system dos com debug all option map file startup,your_c_file |
; |
; TODO: |
; - display stack statistics on program termination if STACKSTAT is enabled |
; - proper Makefiles |
; - many more (optional) things while keeping it small :-) |
.8086 |
IFNDEF STACKSIZE |
STACKSIZE = 400h |
ENDIF |
DGROUP group _TEXT,_DATA,CONST,CONST2,_BSS,_STACK |
extrn "C",main : near |
public _cstart_, _small_code_ |
_TEXT segment word public 'CODE' |
org 100h |
_small_code_ label near |
_cstart_ proc |
; DOS puts the COM program in the largest memory block it can find |
; and sets SP to the end of this block. On top of that, it reserves |
; the entire memory (not only the process' block) to the program, which |
; makes it impossible to allocate memory or run child processes. |
; for this reasons it is beneficial to resize the memory block we occupy |
; into a more reasonable value |
@verify_stack_size: |
cmp sp,offset DGROUP:_stack_end_ |
ja @resize_mem |
mov dx,offset @memerr |
jmp _panic_ |
@memerr db 'MEMERR$' |
; step 2: resize our memory block to sp bytes (ie. sp/16 paragraphs) |
@resize_mem: |
mov sp,offset DGROUP:_stack_end_ |
IFDEF STACKSTAT |
mov [_stack_low_],sp |
ENDIF STACKSTAT |
mov ah,4ah |
mov bx,sp |
add bx,0fh |
shr bx,1 |
shr bx,1 |
shr bx,1 |
shr bx,1 |
int 21h |
; clear _BSS to be ANSI C conformant |
mov di,offset DGROUP:_BSS |
mov cx,offset DGROUP:_STACK |
sub cx,di |
shr cx,1 |
xor ax,ax |
cld |
rep stosw |
call main |
mov ah,4ch |
int 21h |
_cstart_ endp |
_panic_ proc |
; output error message in DX, then terminate with FF |
mov ah,9 |
int 21h |
mov ax,4cffh ; terminate if not enough stack space |
int 21h |
_panic_ endp |
IFNDEF NOSTACKCHECK |
public __STK |
__STK proc |
; ensures that we have enough stack space left. the needed bytes are |
; given in AX. panics if stack low. |
sub ax,sp ; subtract needed bytes from SP |
neg ax ; SP-AX = -(AX-SP) |
cmp ax,offset DGROUP:_STACK - 2 ; -2 is to compensate for __STK ret addr |
jae @l1 ; enough stack => return, else panic |
int 3 ; trap into debugger |
mov dx,offset @stkerr |
add sp,200h ; make sure we have enough stack to call DOS |
jmp _panic_ |
@stkerr db 'STKERR$' |
@l1: |
IFDEF STACKSTAT ; update lowest stack pointer if statistics enabled |
cmp [_stack_low_],ax |
jbe @r |
mov [_stack_low_],ax |
ENDIF STACKSTAT |
@r: |
ret |
__STK endp |
ENDIF |
_DATA segment word public 'DATA' |
_DATA ends |
CONST segment word public 'DATA' |
CONST ends |
CONST2 segment word public 'DATA' |
CONST2 ends |
_BSS segment word public 'BSS' |
IFDEF STACKSTAT |
public _stack_low_ |
_stack_low_: dw 1 dup(?) |
ENDIF STACKSTAT |
_BSS ends |
; stack definition, available memory is checked at runtime |
; defined as segment so that linker may detect .COM size overflow |
_STACK segment para public 'TINY_STACK' |
public _stack_end_ |
db STACKSIZE dup(?) |
_stack_end_: |
_STACK ends |
_TEXT ends |
end _cstart_ |
//wmincrt/tags/20231113/tests/hello/build.bat |
---|
0,0 → 1,3 |
wasm -q -DNOSTACKCHECK ..\..\startup.asm |
wcc -q -os -s hello.c |
wlink system dos com option quiet option map name hello file startup,hello |
//wmincrt/tags/20231113/tests/hello/hello.c |
---|
0,0 → 1,28 |
typedef unsigned size_t; |
size_t strlen( const char *text ) |
{ |
size_t len = 0; |
while (text[len]) len++; |
return len; |
} |
/* pragma aus generates more efficient machine code than _asm {} blocks */ |
extern unsigned dos_f40h(unsigned handle, const char* data, size_t len); |
#pragma aux dos_f40h = \ |
"mov ah,40h" \ |
"int 21h" \ |
parm [bx] [dx] [cx] \ |
modify [ax] |
void puts( const char *text ) |
{ |
dos_f40h(1, text, strlen( text )); |
} |
int main( void ) |
{ |
puts( "Hello, World\n" ); |
return 0; |
} |
//wmincrt/tags/20231113/tests/stkchk/build.bat |
---|
0,0 → 1,3 |
wasm -q -d1 -DSTACKSTAT ..\..\startup.asm |
wcc -q -os -d2 stkchk.c |
wlink system dos com debug all option quiet option map name stkchk file startup,stkchk |
//wmincrt/tags/20231113/tests/stkchk/stkchk.c |
---|
0,0 → 1,7 |
/* This should trigger a stack overflow */ |
int main( void ) |
{ |
main(); |
return 0; |
} |
//wmincrt/trunk/startup.asm |
---|
0,0 → 1,157 |
; WMINICRT - minimal runtime for (Open) Watcom C to generate DOS .COM files |
; |
; The default behaviour of the runtime is: |
; - sets up a stack of 400H bytes |
; - releases additional memory beyond stack to DOS |
; - panics on initialization, if not enough memory for stack size |
; - panics if running out of stack during execution |
; |
; WASM definitions: |
; STACKSIZE=<value> define stack size other than 400h |
; NOSTACKCHECK do not assemble __STK function |
; STACKSTAT remember the minimum SP, maintained by __STK__ |
; and exported via _stack_low_. |
; |
; To build an executable without build- and linker scripts run: |
; wasm startup.asm |
; wcc -0 -bt=dos -ms -os -zl your_c_file.c |
; wlink system dos com file startup,your_c_file |
; To change the stack size, add -DSTACKSIZE=<value> to the wasm call |
; |
; To compile without stack checking: |
; a) compile this startup file with wasm -DNOSTACKCHECK startup.asm |
; b) call the C compiler with -s flag |
; |
; To build a debug version of your program: |
; wasm -d1 startup.asm |
; wcc -bt=dos -ms -d2 -zl your_c_file.c |
; wlink system dos com debug all option map file startup,your_c_file |
; |
; TODO: |
; - display stack statistics on program termination if STACKSTAT is enabled |
; - proper Makefiles |
; - many more (optional) things while keeping it small :-) |
.8086 |
IFNDEF STACKSIZE |
STACKSIZE = 400h |
ENDIF |
DGROUP group _TEXT,_DATA,CONST,CONST2,_BSS,_STACK |
extrn "C",main : near |
public _cstart_, _small_code_ |
_TEXT segment word public 'CODE' |
org 100h |
_small_code_ label near |
_cstart_ proc |
; DOS puts the COM program in the largest memory block it can find |
; and sets SP to the end of this block. On top of that, it reserves |
; the entire memory (not only the process' block) to the program, which |
; makes it impossible to allocate memory or run child processes. |
; for this reasons it is beneficial to resize the memory block we occupy |
; into a more reasonable value |
@verify_stack_size: |
cmp sp,offset DGROUP:_stack_end_ |
ja @resize_mem |
mov dx,offset @memerr |
jmp _panic_ |
@memerr db 'MEMERR$' |
; step 2: resize our memory block to sp bytes (ie. sp/16 paragraphs) |
@resize_mem: |
mov sp,offset DGROUP:_stack_end_ |
IFDEF STACKSTAT |
mov [_stack_low_],sp |
ENDIF STACKSTAT |
mov ah,4ah |
mov bx,sp |
add bx,0fh |
shr bx,1 |
shr bx,1 |
shr bx,1 |
shr bx,1 |
int 21h |
; clear _BSS to be ANSI C conformant |
mov di,offset DGROUP:_BSS |
mov cx,offset DGROUP:_STACK |
sub cx,di |
shr cx,1 |
xor ax,ax |
cld |
rep stosw |
call main |
mov ah,4ch |
int 21h |
_cstart_ endp |
_panic_ proc |
; output error message in DX, then terminate with FF |
mov ah,9 |
int 21h |
mov ax,4cffh ; terminate if not enough stack space |
int 21h |
_panic_ endp |
IFNDEF NOSTACKCHECK |
public __STK |
__STK proc |
; ensures that we have enough stack space left. the needed bytes are |
; given in AX. panics if stack low. |
sub ax,sp ; subtract needed bytes from SP |
neg ax ; SP-AX = -(AX-SP) |
cmp ax,offset DGROUP:_STACK - 2 ; -2 is to compensate for __STK ret addr |
jae @l1 ; enough stack => return, else panic |
int 3 ; trap into debugger |
mov dx,offset @stkerr |
add sp,200h ; make sure we have enough stack to call DOS |
jmp _panic_ |
@stkerr db 'STKERR$' |
@l1: |
IFDEF STACKSTAT ; update lowest stack pointer if statistics enabled |
cmp [_stack_low_],ax |
jbe @r |
mov [_stack_low_],ax |
ENDIF STACKSTAT |
@r: |
ret |
__STK endp |
ENDIF |
_DATA segment word public 'DATA' |
_DATA ends |
CONST segment word public 'DATA' |
CONST ends |
CONST2 segment word public 'DATA' |
CONST2 ends |
_BSS segment word public 'BSS' |
IFDEF STACKSTAT |
public _stack_low_ |
_stack_low_: dw 1 dup(?) |
ENDIF STACKSTAT |
_BSS ends |
; stack definition, available memory is checked at runtime |
; defined as segment so that linker may detect .COM size overflow |
_STACK segment para public 'TINY_STACK' |
public _stack_end_ |
db STACKSIZE dup(?) |
_stack_end_: |
_STACK ends |
_TEXT ends |
end _cstart_ |
//wmincrt/trunk/tests/hello/build.bat |
---|
0,0 → 1,3 |
wasm -q -DNOSTACKCHECK ..\..\startup.asm |
wcc -q -os -s hello.c |
wlink system dos com option quiet option map name hello file startup,hello |
//wmincrt/trunk/tests/hello/hello.c |
---|
0,0 → 1,28 |
typedef unsigned size_t; |
size_t strlen( const char *text ) |
{ |
size_t len = 0; |
while (text[len]) len++; |
return len; |
} |
/* pragma aus generates more efficient machine code than _asm {} blocks */ |
extern unsigned dos_f40h(unsigned handle, const char* data, size_t len); |
#pragma aux dos_f40h = \ |
"mov ah,40h" \ |
"int 21h" \ |
parm [bx] [dx] [cx] \ |
modify [ax] |
void puts( const char *text ) |
{ |
dos_f40h(1, text, strlen( text )); |
} |
int main( void ) |
{ |
puts( "Hello, World\n" ); |
return 0; |
} |
//wmincrt/trunk/tests/stkchk/build.bat |
---|
0,0 → 1,3 |
wasm -q -d1 -DSTACKSTAT ..\..\startup.asm |
wcc -q -os -d2 stkchk.c |
wlink system dos com debug all option quiet option map name stkchk file startup,stkchk |
//wmincrt/trunk/tests/stkchk/stkchk.c |
---|
0,0 → 1,7 |
/* This should trigger a stack overflow */ |
int main( void ) |
{ |
main(); |
return 0; |
} |