можно - см. внизу
это чуть-чуть меняет подход к программированию, но не сильно.
В первую очередь - несомненно. А потом уже от языка (и можете меня не пытаться переубедить в том, что в j2ee нет “встроенных” memory leak 
- Copyright (c) 1989, 1990 William Jolitz. All rights reserved.
- Written by William Jolitz 7/89
- Redistribution and use in source and binary forms are freely permitted
- provided that the above copyright notice and attribution and date of work
- and this paragraph are duplicated in all such forms.
- THIS SOFTWARE IS PROVIDED ``AS IS’’ AND WITHOUT ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- This program allows the bootstrap load of GCC cross compiled
- 32 bit protected mode absolute programs onto the obtuse architecture
- of PC AT/386, destroying the running DOS in the process.
- Currently works with TURBO C 1.5 & MASM 5.0, relies on farmalloc().
*/
#pragma inline
#include <io.h>
#include <fcntl.h>
#include <alloc.h>
#include <dos.h>
#include <sys\stat.h>
#include “exec.h”
#define PGSIZE 4096
#define CLOFSET (PGSIZE - 1) /* 386 page roundup */
/* Header record of BSD UNIX executable file */
struct exec exec;
long far_read(), to_long();
char far *to_far();
char far *add_to_far(char far *p, long n);
/* Get a file we can open, attempt to load it */
main(argc, argv)
char *argv;
{ int fd, i;
long addr, totalsz;
char far *base;
if (argc != 2) {
printf("usage: boot <filename>
");
exit(1);
}
fd = open(argv[1], O_BINARY);
if (fd < 0) {
printf("boot: Cannot open file "%s"
", argv[1]);
exit(1);
}
/* Reasonable file to load? */
i = read(fd, (char *)&exec, sizeof exec);
if (i != sizeof exec ||
(exec.a_magic != OMAGIC && exec.a_magic != NMAGIC
&& exec.a_magic != ZMAGIC)) {
printf("Not a recognized object file format
");
exit(1);
}
/* Allocate buffer for temporary copy of protected mode executable
Buffer space requirements: |<--a.out------------>| pageroundup heap */
totalsz = exec.a_text + exec.a_data + exec.a_bss + 4096L + 20*1024L;
/* Pad with trailing portion to put protected mode entry code in */
base = farmalloc(totalsz + 641024L);
if (base == 0) {
printf("Cannot allocate enough memory
");
exit(1);
}
/ Load Instruction (e.g. text) portion of file /
printf(“Text %ld”, exec.a_text);
if (far_read(fd, base, exec.a_text) != exec.a_text)
goto eof;
/ Load Data portion of file */
addr = exec.a_text;
/* Adjust for page alignment for pure procedure format */
if (exec.a_magic == NMAGIC && (addr & (PGSIZE-1)))
while (addr & CLOFSET)
* add_to_far(base, addr++) = 0;
printf("
Data %ld", exec.a_data);
if (far_read(fd, add_to_far(base,addr), exec.a_data) != exec.a_data)
goto eof;
/* Clear Uninitialized data (BSS) space */
addr += exec.a_data;
printf("
Bss %ld", exec.a_bss);
for ( ; addr < totalsz; )
* add_to_far(base,addr++) = 0;
if(exec.a_entry)
printf("
Start 0x%lx", exec.a_entry);
#ifdef CKSUM
/* Optionally calculate checksum to validate against cross host's copy. */
far_cksum(base, addr-1L);
#endif CKSUM
printf("
");
/* Effect copydown to absolute 0 and entry into protected mode at
location "a_entry". */
transfer(base, totalsz, exec.a_entry);
/* NOTREACHED */
eof:
printf(" - File incomplete, load aborted
");
exit(1);
}
/* We use the routines below to always keep far pointers normalized
- to simplify comparision/subtraction. */
char far *to_far(l) long l; {
unsigned seg, offs;
seg = l>>4;
offs = l & 0xf;
return(MK_FP(seg,offs));
}
long to_long(f) char far *f; {
unsigned long l;
l = FP_SEG(f)*16L + (unsigned long)FP_OFF(f);
return(l);
}
char far *add_to_far(f,l) char far *f; long l; {
return(to_far(to_long(f)+l));
}
char far *normalize(f) char far *f; {
unsigned seg,offs ;
/* add in offset */
seg = FP_SEG(f); offs = FP_OFF(f);
seg += (offs >> 4) ; offs &= 0xf ;
return(MK_FP (seg, offs));
}
/* read() that works anywhere in DOS address space for any size data,
-
works via bounce buffer. Not designed for speed or elegance. */
long far_read(io, base, len) int io; long len; char far *base; {
char far *fp;
/* normalize far pointer to handle segment rollover case */
fp = base = normalize(base);
while (len) {
static char dbuf[PGSIZE];
long rlen,tlen;
/* bounce buffer between my data segment and ultimate dest */
tlen = (len > PGSIZE)? PGSIZE : len;
if ((rlen = read (io, dbuf, tlen)) < 0) return (rlen);
/* shoot into place */
movedata (_DS, (unsigned)dbuf, FP_SEG(fp), FP_OFF(fp), rlen);
/* update transfer address and count */
fp = add_to_far(fp, rlen);
len -= rlen ;
if (tlen != rlen) break ;
}
return (to_long(fp) - to_long(base));
}
extern far protentry(); /* known to be less than 0x200 bytes long */
extern far gatea20();
/* set up to transfer to 386 program; call protentry to do the dirty work. */
transfer(base, len, entry) char far *base; long len, entry; {
unsigned seg,offs ;
long rbase;
char far *fp;
/* Copy code to top of the system and execute there. This keeps it
from getting stepped on. */
/* make 32 bit address */
rbase = to_long(base);
fp = add_to_far(base,len);
seg = FP_SEG(fp); offs = FP_OFF(fp);
/* protect possible conflict of top paragraph of bss */
if (offs) seg++ ;
/* force to protentry's offset so offsets agree */
offs = FP_OFF(&protentry);
movedata (FP_SEG(&protentry), offs, seg, offs, PGSIZE);
/* degate A20 - from now on, full physical memory address bus */
gatea20();
/* enter prot_entry program, relocated to top of loaded program, via
intersegment return */
asm push word ptr rbase+2 ;
asm push word ptr rbase ;
asm push word ptr len+2 ;
asm push word ptr len ;
asm push word ptr entry+2 ;
asm push word ptr entry ;
asm push word ptr seg;
asm push word ptr offs;
asm db 0cbh; /* lret - intersegment return */
/* within protentry: go into 32 bit mode, copy entire system to 0 with
single string instruction, intrasegment jump to entry point */
printf("protentry returned?!?
");
exit(1);
/* NOTREACHED */
}
#ifdef CKSUM
/* 16 bit checksum of program. */
far_cksum(base, len) long len; char far *base; {
char far tmp;
unsigned seg,offs ;
long nbytes,sum, tlen;
tmp = base;
sum = 0;
nbytes = 0;
while (len) {
/ normalize far pointer to handle segment rollover case */
tmp = normalize(tmp);
/* Do a page at a time */
tlen = (len > PGSIZE)? PGSIZE : len;
len -= tlen ;
while (tlen--) {
nbytes++;
if (sum&01)
sum = (sum>>1) + 0x8000;
else
sum >>= 1;
sum += *tmp++ ;
sum &= 0xFFFF;
}
}
printf("
Checksum %05lu%6ld ", sum, (nbytes+CLSIZE)/PGSIZE);
}
#endif CKSUM