Thread overview
How do I specify near call to make static object to construct?
Jul 10, 2001
Kiyuki
Jul 10, 2001
Walter
Jul 10, 2001
Kiyuki
Jul 10, 2001
Walter
Jul 10, 2001
Kiyuki
Jul 12, 2001
Walter
July 10, 2001
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.

July 10, 2001
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.
>


July 10, 2001
> 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

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.

July 10, 2001
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,
>like -ms
>> 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.
>


July 10, 2001
"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.

July 12, 2001
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.
>