Tuesday, October 6, 2015

C language : Memory Layout 2



Well ...I thought that the first post would be enough for this thing, but it turns out that still more is needed.


My friend was asked one question : Will the executable build on windows will work on Linux.


Offcourse the answer is NO, as we have seen many a times practically. But Why Not ?


The C code which we write is same for both, we can use the .C file and work on both the system.


So where does the difference occurs.  Is it due to Compilers  GCC vs Visual Studio.  ?


OS  Windows vs Linux ? 


So again I am trying to find out what could be the reason.




So starting first, the basic steps involved in  C code to Executable are




1)  Preprocessing :  Can I use preprocessed file or one system to another ?

2) C code to Assembly Code : Done by Compiler  :  Can I use  this code file across system ?
 
3) Assembly Code to Object Code : Done by Linker : Same question

4) Object Code to Executable : Done by Loader :




Now the first thing I will do , is have GCC on Windows , so that atleast we have same file extension .


 I installed MinGW, 


Step 1)  Install MinGW from its website. Choose only C and C++ option.
Step 2) http://stackoverflow.com/questions/25542055/mingw-c-compiler-zlib1-dll-missing-error/25542347   :  Apply changes as per 2nd option
Step 3)  C:/MinGW/bin should be present in your environmental variables.






Now once this much is done,so lets dig deeper.




On Windows , I made a small program


main.c


void main()
{
}


and  compiled using




gcc -o check main.c --save-temps   // This will save the  .I , .S , .O  and .EXE file.

Same I will be compiling on Linux,

Now it turns out thing are not so easy as I was expecting.

I will be uploading the FILES later.

The window/mingw   .I extension which is for preprocessed file differs slightly from the Linux generated preprocessed file for same code.

Even though the diff was minimal, later I can see how much difference was present.

Now the assembler file of both were different, the main difference was the function call.

In winodws  it was _main  in Linux  main.


So I copied the windows preprocessed file to Linux , and generated assembly code there.

--------Some extension and command-----------

To generated preprocessed file

gcc -E main.c -o main.i   // I is extension

To generate assembly code

gcc -S main.i -o main.s  // S is extension

To generate object code

gcc -c  main.s -o main.o  // O is extension

To generate executable

gcc -o main.o  outfile.out  // .out is extension

---------------------------------------------------------------

now when I used Windows preprocessed file and generated assembly code in Linux, the file generated was same as the assembly code file for linux.

But when I generated the object code file, it differs hugely.

WHY??????  Not having the faintest idea.

Hence I am stopping this post here, until me or someone else do further debugging.

-----------------------------------------------------------------------------------------------------------------

Some question to answer .

What is assembler ?
Difference between assembly and object code ?

there was pretty interesting post I found out.

http://stackoverflow.com/questions/28490124/reverse-engineer-assembly-code-to-c-code






No comments:

Post a Comment