Link to home
Start Free TrialLog in
Avatar of ankuratvb
ankuratvbFlag for United States of America

asked on

A Weird C Experiment

Hey all,

What i want to do is that instead of calling my function, which starts execution of my code,main() ,I want to call it something else say niam()
I know that C has some startup code in C0*.obj files which search for a function called main()
I even changed all calls ro main as niam.
What i achieved is the compiler did start searching for niam instead of main.

But as soon as i try to execute my code with niam() instead of main(),my compiler crashes saying that an exception occured in c0.asm(Invalid segment)

I believe C creates a temporary c0.asm file & deletes it after compilation.

How to Bring about my experiment.

This is out of pure curiosity & this is of no particular purpose
Avatar of ankuratvb
ankuratvb
Flag of United States of America image

ASKER

Oh ,I forgot.

I am using the TurboC++ DOS compiler & even tc.exe had a few references to main().
I changed even those to point to niam()

Still didnt work.Same error.

Avatar of Jase-Coder
Jase-Coder

try using

#include<stdio.h>

#define naim main()

naim
{
   ......
   .......
}

that might work
void  niam ()
{
  // Do the niam stuff
}

void  main ()
{
  niam() ;
}

This works too.
C startup code is invariably poorly documented and not intended to be tweaked like this.  Chances are that the special case of main is built into the compiler, the linker, the C startup code, and maybe even the OS startup code.  Understanding this code is important to folks who maintain these components, but not to the overwhelming majority of people using C.

I can see how you might find this an interesting experiment.  My gut feel is that the effort it takes is far more than you'll actually get out of it.  If you really do want to work on this, I'd suggest starting with Linux (or FreeBSD) where you can get all of the source code.  That will show you an example of this, but it won't be portable to MS-DOS or MS Windows.

The two solutions by Jase-Coder and stsanz are hacks that don't do what I think you want to do, but I think you know that already.

Gary
It has been a very long time since I did something like this and it was with
the Lattice or Microsoft C compiler (I can't remember which).  Basically,
it is really difficult to mess with the C runtime startup code, crt0 (although
I did it then).  In any case, crt0 called _main, which in turn called main.

Although it is difficult to override crt0 in the link process, _main was just
pulled from one of the default link libraries.  I simply defined my own _main
that did what I wanted.  
Hey All,

Jase COder & stsanz ,those are childish tricks which i know & dont want to do.

What i want is that without writing any additional code such as a #define or a fn.call from main
the compiler should automatically search for niam instead of main & execute it.

The changes that i made in the c0*.obj & the tc.exe file did solve my problem to an extent
It did then search for niam instead of main but on executing crashed my compiler saying
an exception occured.

Anybody who has an indepth knowledge of the C compiler & assembly might solve my problem

I wanted to do this on my Msdos COmpiler
i have no idea whether this is gonna help u or not, but, u can see the asm listing of a file by (maybe u alredy know it) :

tcc -s a.c

this will create a a.asm file that contains the assembly code corresponding to a.c
ASKER CERTIFIED SOLUTION
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks Kdo for ur reply.It seems the most logical explanation for my query.

>So Borland utilizes the small program segment that requires the C program to being with function main().  As soon as the startup program complete its setup it calls your main() program.
c0.asm is calling main().  Since you didn't provide a main() function, c0.asm is branching to an illegal address, probably NULL.

But Please tell me,

In the compiler the program segment that has been defined such that it requires a main(),can't it be changed to define the segment such that it requires a fn other than main()

The c0*.obj files come in after the asm file has been created so the definition for main lies in the tc.exe file itself.
The c0*.obj files just call the fn main() ,as Kdo said

What I believe is that the compiler creates a C0.asm file with a procedure _main.This is defined in the tc.exe file(i think) where in the debugger if you display contents, it says <template>main _main <template>.

I changed that to define _niam instead of _main,so that i have a _niam procedure in c0.asm,& i made the c0*.obj files call a niam() fn instead of main().
but it didnt work.

Any help???

If you've modified the name "main" in the c0.asm file to be "niam" and assembled the code you should be all set.

The one other step that you'll likely have to take is to explicitly link your modules without linking the "default" c0*.obj module.  The IDE will always try to link in the default module so you'll have to call TLINK from the command line.

Kent
The problem is that there's startup code in c0.obj that does all kinds of critical things, like setting up data segments,, exception stacks,
exception handlers,  call stacks, intializing stdin and stdout and stderr, setting the CPU IEEE flaoting point status properly, initializing the static data segment to zeroes, parsing out the commmand line arguments, waking up the system API's, preloading any PRELOAD segments, initialing the malloc arena headers, perhaps much more.

Only THEN does c0.obj call main with parameters argc and argv. then when main returns, it has to undo a lot of what it did, then it exits to the operating system.

Many compiler vendors give you a copy of c0.asm for your persual pleasure, look at that ifyou want
to learn the real nitty-gritty of C program startup.  There's often a lot of rather tricky and poorly
documented code in tehre, so don't feel too bad if you don't understand it all.


So you'll have a HECK of a hard time getting any C code to run without all that initialization.
At the very least you wont have access to argc, argv, stdin, stdout, malloc(), or any library routine that assumes its global static data is initialized to zero.  On many CPU's you won't even have a call stack or a data segment, so you cant set any variables or call any routines.  That makes for a very very dull C program!


Regards,
grg88



Hi grg,

Changing your name will hardly result in anonymity around here.  ;)

I assumed that ankuratvb has the asm source code available to him, or did a binary edit of the startup code to replace "main" with "niam".  Either should get him past renaming "main", which is strictly an exercise in futility.  When this question appears on the board it's usually qualified with how it was asked at an interview and the poster wants to know.  I've not seen anyone determined enough to actually do it.  (And once accomplished I hope that it's allowed to die!)


Good points, all of that.
Kent
Thanks All of u for your comments!!

To Kdo,Believe me Kent i am determined to do such a thing as mentioned.And im still in college
so this wasnt asked at an interview,Just out of curiosity

I wasnt able to access c0.asm.i got the asm listing of my code thru the TCC -s option which gives
me the asm program of my code.

But the problem is that TCC uses a different technique to compile & execute than TC,the normal compiler
Thats because it doesnt use any of the c0*.obj files to call main().It calls it from the TCC exe itself

I dont understand why TC gives me an invalid segment error.i have changed my compiler so that it doesnt
require a main() any more.It requires a fn named niam() instead.

If what u guys are saying is correct ,then if i have a main() in my code,it should execute because then there
will be a procedure called main in my c0.asm file for that code and when main() is called from the startup files
it should execute.

But in my case it doesnt.

But also my problem is that if i give a niam() fn,it gives me an invalid segment error.

Guys Help me out here!!

Can anyone guide me so that i can run my c code without main but niam() instead

Anyone has any Suggestions???
Kent ,im sure u must be having an idea.Help me cos im currently out of ideas
Anyway,do u know of a good assembly site

Hi ankuratvb,

After your changes, does the new program contain a transfer address?  The new program has to have a "starting location".  Without one, the module will look like a cross between library item that can be linked with other modules and a DLL, but not really be either one.  If the transfer address isn't defined the program could be starting with a branch to zero, which is of course, an "invalid segment".


Kent