www.digitalmars.com         C & C++   DMDScript  

c++.dos.16-bits - How do I specify near call to make static object to construct?

reply "Kiyuki" <sakura tennodai.com> writes:
Hello,

I'm programming a startup routine for WonderSwan/WonderWitch/Digital Mars
C++.

Current version of sc compiles CPP source file having static objects using
constructor,
and it makes far functions ___SI?%filename..../___SD?%filename.... and put
their addresses
into DATA segment with dd (dword ptr) directive.

I want to make them "near functions" and put their offsets in TEXT segment
with
dw (word ptr) directive.

Show me how to specify options to the compiler to do so.

Thanks.
Jul 10 2001
parent reply "Walter" <walter digitalmars.com> writes:
You'll have to compile those modules with a near code memory model, like -ms
or -mc. I assume you are compiling for 16 bits. -Walter

Kiyuki wrote in message <9iea60$ujd$1 digitaldaemon.com>...
Hello,

I'm programming a startup routine for WonderSwan/WonderWitch/Digital Mars
C++.

Current version of sc compiles CPP source file having static objects using
constructor,
and it makes far functions ___SI?%filename..../___SD?%filename.... and put
their addresses
into DATA segment with dd (dword ptr) directive.

I want to make them "near functions" and put their offsets in TEXT segment
with
dw (word ptr) directive.

Show me how to specify options to the compiler to do so.

Thanks.

Jul 10 2001
parent reply "Kiyuki" <sakura tennodai.com> writes:
 You'll have to compile those modules with a near code memory model,

 or -mc. I assume you are compiling for 16 bits. -Walter

Indeed, with options -ms or -mc, sc generates near constuctor/destructor. But ___SI%foo_cpp.../___SD%foo_cpp.... as far function. These "far" functions call "constructor/destructor near functions" for static object from startup routine. For example: // foo.cpp #include <string.h> #include <stdio.h> class Init { public: Init(); ~Init(); }; Init::Init() { } Init::~Init() { } Init b; int main() { Init a; printf("digital mars c++\n"); return 0; } compile with -ms, generates near constructor ??0Init QAC XZ, near destructor ??1Init QAC XZ, static object far initializer ___SI?%foo_cpp179731330_, and static object far cleanuper ___SD?%foo_cpp179731330_. The far initializer calls near constructor Init::Init() in order to construct static object b. I want to make initializer and cleanuper as near function. _TEXT segment assume CS:_TEXT ;Init::Init() { ??0Init QAC XZ: 55 push BP 8B EC mov BP,SP 8B 46 04 mov AX,4[BP] ;} 5D pop BP C2 02 00 ret 2 ; ;Init::~Init() { ??1Init QAC XZ: C2 02 00 ret 2 ;} ; ;Init b; ; ;int main() { _main: 55 push BP 8B EC mov BP,SP 50 push AX ; Init a; 8D 46 FE lea AX,-2[BP] 50 push AX E8 E8 FF call near ptr ??0Init QAC XZ ; ; printf("digital mars c++\n"); 1E push DS B8 00 00 mov AX,offset DGROUP:_DATA 50 push AX E8 00 00 call near ptr ?printf YAHPFDZZ 8D 46 FE lea AX,-2[BP] 50 push AX E8 E3 FF call near ptr ??1Init QAC XZ ; ; return 0; 83 C4 04 add SP,4 31 C0 xor AX,AX ;} 8B E5 mov SP,BP 5D pop BP C3 ret ___SD?%foo_cpp179731330_: B8 00 00 mov AX,offset DGROUP:?b 3VInit A 50 push AX E8 D3 FF call near ptr ??1Init QAC XZ CB retf ___SI?%foo_cpp179731330_: B8 00 00 mov AX,offset DGROUP:?b 3VInit A 50 push AX E8 C1 FF call near ptr ??0Init QAC XZ 0E push CS B8 30 00 mov AX,offset _TEXT:___SD?%foo_cpp179731330_ 50 push AX 9A 00 00 00 00 call far ptr __fatexit 83 C4 04 add SP,4 CB retf _TEXT ends _DATA segment D0 db 064h,069h,067h,069h,074h,061h,06ch,020h db 06dh,061h,072h,073h,020h,063h,02bh,02bh db 00ah,000h _DATA ends CONST segment CONST ends _BSS segment _BSS ends XIFCB segment XIFCB ends XIFU segment dd _TEXT:___SI?%foo_cpp179731330_ XIFU ends Thanks.
Jul 10 2001
parent reply "Walter" <walter digitalmars.com> writes:
I'm afraid there isn't a compiler switch to do what you want. Perhaps
there's another solution - why do you want them to be near? -Walter

Kiyuki wrote in message <9ieh1a$126d$1 digitaldaemon.com>...
 You'll have to compile those modules with a near code memory model,

 or -mc. I assume you are compiling for 16 bits. -Walter

Indeed, with options -ms or -mc, sc generates near constuctor/destructor. But ___SI%foo_cpp.../___SD%foo_cpp.... as far function. These "far" functions call "constructor/destructor near functions" for static object from startup routine. For example: // foo.cpp #include <string.h> #include <stdio.h> class Init { public: Init(); ~Init(); }; Init::Init() { } Init::~Init() { } Init b; int main() { Init a; printf("digital mars c++\n"); return 0; } compile with -ms, generates near constructor ??0Init QAC XZ, near destructor ??1Init QAC XZ, static object far initializer ___SI?%foo_cpp179731330_, and static object far cleanuper ___SD?%foo_cpp179731330_. The far initializer calls near constructor Init::Init() in order to construct static object b. I want to make initializer and cleanuper as near function. _TEXT segment assume CS:_TEXT ;Init::Init() { ??0Init QAC XZ: 55 push BP 8B EC mov BP,SP 8B 46 04 mov AX,4[BP] ;} 5D pop BP C2 02 00 ret 2 ; ;Init::~Init() { ??1Init QAC XZ: C2 02 00 ret 2 ;} ; ;Init b; ; ;int main() { _main: 55 push BP 8B EC mov BP,SP 50 push AX ; Init a; 8D 46 FE lea AX,-2[BP] 50 push AX E8 E8 FF call near ptr ??0Init QAC XZ ; ; printf("digital mars c++\n"); 1E push DS B8 00 00 mov AX,offset DGROUP:_DATA 50 push AX E8 00 00 call near ptr ?printf YAHPFDZZ 8D 46 FE lea AX,-2[BP] 50 push AX E8 E3 FF call near ptr ??1Init QAC XZ ; ; return 0; 83 C4 04 add SP,4 31 C0 xor AX,AX ;} 8B E5 mov SP,BP 5D pop BP C3 ret ___SD?%foo_cpp179731330_: B8 00 00 mov AX,offset DGROUP:?b 3VInit A 50 push AX E8 D3 FF call near ptr ??1Init QAC XZ CB retf ___SI?%foo_cpp179731330_: B8 00 00 mov AX,offset DGROUP:?b 3VInit A 50 push AX E8 C1 FF call near ptr ??0Init QAC XZ 0E push CS B8 30 00 mov AX,offset _TEXT:___SD?%foo_cpp179731330_ 50 push AX 9A 00 00 00 00 call far ptr __fatexit 83 C4 04 add SP,4 CB retf _TEXT ends _DATA segment D0 db 064h,069h,067h,069h,074h,061h,06ch,020h db 06dh,061h,072h,073h,020h,063h,02bh,02bh db 00ah,000h _DATA ends CONST segment CONST ends _BSS segment _BSS ends XIFCB segment XIFCB ends XIFU segment dd _TEXT:___SI?%foo_cpp179731330_ XIFU ends Thanks.

Jul 10 2001
parent reply "Kiyuki" <sakura tennodai.com> writes:
"Walter" <walter digitalmars.com> wrote in message
news:9if7l8$1m35$1 digitaldaemon.com...
 I'm afraid there isn't a compiler switch to do what you want. Perhaps
 there's another solution - why do you want them to be near? -Walter

WonderSwan is a mobile game machine made by BANDAI, Japan and WonderWitch is a game development kit for WonderSwan. I'm using DMC++ to run programs. WonderWitch programs are compiled by the process below: (1) Comiling c/c++ source file with -msw option. (2) Linking startup routine for WW and object files to EXE. (3) Exe2com-ing the EXE file to BIN. (4) Copying BIN to frash ROM of WonderWitch. WonderWitch runs user programs from startup: (a) copying data defined in DATA segment to RAM, (b) clearing RAM region associated with BSS segment, (c) assigning SP to predefined value, and (d) calling _main. I'm trying to rewrite startup to call static initializer/cleanuper, but on this WW architecture and with exe2com, segment/offset information of far function stored with DD directive is lost or rotten in RAM. I'm afraid exe2com (by Chris Dunford/The Cove Software Group) fails to get segment/offset information in EXE. For reference, this program run successfully: void near foo() { ... } typedef void (near*PVNFV)(); static PVNFV p[ ] = { &foo }; int main() { p[0](); } But this program fails to run: void far bar() { ... } typedef void (far*PVFFV)(); static PVFFV q[ ] = { &bar }; int main() { q[0](); } Because q[0] has meaningless value.
Jul 10 2001
parent "Walter" <walter digitalmars.com> writes:
COM files (produced by exe2com) cannot have segment references in them,
which is what happens with a dd function reference. Hence, exe2com should
fail if files have far references in them.

Your best bet at the moment is to not use static constructors, and instead
use the technique you outlined below.

-Walter

Kiyuki wrote in message <9ifcj1$1p45$1 digitaldaemon.com>...
"Walter" <walter digitalmars.com> wrote in message
news:9if7l8$1m35$1 digitaldaemon.com...
 I'm afraid there isn't a compiler switch to do what you want. Perhaps
 there's another solution - why do you want them to be near? -Walter

WonderSwan is a mobile game machine made by BANDAI, Japan and WonderWitch is a game development kit for WonderSwan. I'm using DMC++ to run programs. WonderWitch programs are compiled by the process below: (1) Comiling c/c++ source file with -msw option. (2) Linking startup routine for WW and object files to EXE. (3) Exe2com-ing the EXE file to BIN. (4) Copying BIN to frash ROM of WonderWitch. WonderWitch runs user programs from startup: (a) copying data defined in DATA segment to RAM, (b) clearing RAM region associated with BSS segment, (c) assigning SP to predefined value, and (d) calling _main. I'm trying to rewrite startup to call static initializer/cleanuper, but on this WW architecture and with exe2com, segment/offset information of far function stored with DD directive is lost or rotten in RAM. I'm afraid exe2com (by Chris Dunford/The Cove Software Group) fails to get segment/offset information in EXE. For reference, this program run successfully: void near foo() { ... } typedef void (near*PVNFV)(); static PVNFV p[ ] = { &foo }; int main() { p[0](); } But this program fails to run: void far bar() { ... } typedef void (far*PVFFV)(); static PVFFV q[ ] = { &bar }; int main() { q[0](); } Because q[0] has meaningless value.

Jul 12 2001