Merge pull request #256 from tkchia/tkchia/pid
plat/msdos86: free up program memory above 64 KiB; also check we have enough memory for BSS
This commit is contained in:
commit
2c3c7a28e2
|
@ -12,6 +12,8 @@
|
|||
|
||||
.sect .text
|
||||
|
||||
#define STACK_BUFFER 128 /* number of bytes to leave for stack */
|
||||
|
||||
begtext:
|
||||
! Make sure we are running under MS-DOS 2 or above.
|
||||
!
|
||||
|
@ -20,9 +22,38 @@ begtext:
|
|||
! segment. (DOS 3+ does; DOS 2.x does not.)
|
||||
movb ah, 0x30
|
||||
int 0x21
|
||||
cbw
|
||||
cmpb al, 2
|
||||
xchg bx, ax
|
||||
jc bad_sys
|
||||
xchg bp, ax
|
||||
jnc ok_sys
|
||||
|
||||
mov dx, bad_sys_msg
|
||||
dos_msg:
|
||||
movb ah, 9
|
||||
int 0x21
|
||||
ret
|
||||
|
||||
ok_sys:
|
||||
! Resize the program's memory control block (MCB) to cover only the
|
||||
! program's near code and data space. Use the starting sp value as
|
||||
! a guide to how much memory we can grab. Abort on any failure.
|
||||
!
|
||||
! As a side effect, this also frees up any memory allocated to our
|
||||
! program beyond 64 KiB. (The freed memory can possibly be used by
|
||||
! e.g. child processes, in the future.)
|
||||
!
|
||||
! Also check that we have some space between the BSS end and the
|
||||
! starting sp.
|
||||
cmp sp, endbss+STACK_BUFFER
|
||||
jb no_room
|
||||
|
||||
movb ah, 0x4a
|
||||
mov bx, sp
|
||||
movb cl, 4
|
||||
shr bx, cl
|
||||
inc bx
|
||||
int 0x21
|
||||
jc no_room
|
||||
|
||||
! Clear BSS.
|
||||
mov di, begbss
|
||||
|
@ -35,11 +66,12 @@ begtext:
|
|||
|
||||
! Get the size of the environment variables plus (if present) the
|
||||
! program name. Also count the number of environment variables.
|
||||
mov es, (0x002C)
|
||||
xor di, di
|
||||
mov es, 0x002C(di)
|
||||
! ax = 0 from above
|
||||
cwd ! dx = count of env. vars.
|
||||
mov cx, -1
|
||||
! cx = 0 from above
|
||||
dec cx ! cx = max. str. bytes to scan
|
||||
scasb ! handle special case of empty env.
|
||||
jz is_empty_env
|
||||
size_env:
|
||||
|
@ -48,7 +80,7 @@ size_env:
|
|||
scasb
|
||||
jnz size_env
|
||||
is_empty_env:
|
||||
cmpb bl, 2
|
||||
cmp bp, 2
|
||||
jz no_argv0
|
||||
scasw
|
||||
repnz scasb
|
||||
|
@ -58,10 +90,9 @@ no_argv0:
|
|||
! onto the stack.
|
||||
mov si, di
|
||||
dec si
|
||||
and si, -2
|
||||
std
|
||||
copy_env:
|
||||
test si, si
|
||||
and si, -2
|
||||
eseg lodsw
|
||||
push ax
|
||||
jnz copy_env
|
||||
|
@ -79,7 +110,7 @@ copy_env:
|
|||
|
||||
! Build up argc, argv[], and envp[].
|
||||
push ax ! output buffer for argc, argv, envp
|
||||
push bx ! MS-DOS version
|
||||
push bp ! MS-DOS version
|
||||
push cx ! env. string data
|
||||
push dx ! count of env. vars.
|
||||
mov ax, 0x0080
|
||||
|
@ -97,13 +128,6 @@ copy_env:
|
|||
push ax
|
||||
call _exit
|
||||
|
||||
bad_sys:
|
||||
mov dx, bad_sys_msg
|
||||
dos_msg:
|
||||
movb ah, 9
|
||||
int 0x21
|
||||
ret
|
||||
|
||||
no_room:
|
||||
mov dx, no_room_msg
|
||||
call dos_msg
|
||||
|
|
|
@ -22,7 +22,7 @@ struct for_main {
|
|||
* Return zero if everything went well, non-zero otherwise.
|
||||
*/
|
||||
int _sys_initmain(char *arg_data, size_t n_env_vars, char *env_data,
|
||||
unsigned msdos_ver, struct for_main *out)
|
||||
unsigned msdos_ver_major, struct for_main *out)
|
||||
{
|
||||
char **argv, **envp;
|
||||
char c, *p, **pp;
|
||||
|
@ -100,7 +100,7 @@ int _sys_initmain(char *arg_data, size_t n_env_vars, char *env_data,
|
|||
* shortword) following the environment variables, so advance p by 3
|
||||
* bytes to get at the program name.
|
||||
*/
|
||||
if ((msdos_ver & 0x00ff) >= 3)
|
||||
if (msdos_ver_major >= 3)
|
||||
{
|
||||
p += 3;
|
||||
argv[0] = p;
|
||||
|
|
Loading…
Reference in a new issue