Domanda

Lots of basic questions are there in my mind. I need to clear them.

Statement 1: A compiler converts a human-readable codes to object codes, and those are converted to a machine code (executable) by linker.

Am I right here?

At wikipedia, it is written that

Object files are produced by an assembler, compiler, or other language
translator, and used as input to the linker.

Question 1: An assembler converts assembly language code (MOV A, B ADD C) to machine code. In case of high-level language like C++, that is generated by linker above. So assembler is not used anywhere. So how can it create an object file as written above?

Intermediate code is generated to make the code run on different architectures.

Question 2: Are *.class (bytecode) files created by java compiler object files? If yes, then can we say that the JVM that runs them is a type of linker (however its not creating the executable)?

Question 3: When we compile a C++ program in Turbo C++, we get *.obj files which are the object files. Can we use them to generate the executable in some other architecture?

È stato utile?

Soluzione

Question 1: yes, an assembler (as, gas, nasm, masm) compiles assembly instructions to object code. In case of high-level languages (H) the compiler compiles H to either another language (for example GHC, the Glorious Haskell Compiler can produce C, but it can also produce C--, and there was an attempt(?) to produce Java), or into object code through intermediate steps (or languages C-- or Core).

Intermediate code can be generated for many reasons: 1. portability for example .class files from java, p-code for Pascal 2. to facilitate code optimisations

Question 2: .class files can be generated by a java compiler, but Scala also generates .class files, and AspectJ (the aspect oriented flavour) also produces .class files. .class files are not object files in the sense that they need the Java Virtual Machine (and the unix linker ld won't link .class files against .o files). The original JVM is an interpreter for .class files, but you can compile java on-the-fly too.

Question 3: Turbo C++ .obj files (compiled on 64 bit intel) would not be happy on a Z80 machine unless the compiler has the option of cross-compiling for another architecture, so in the case of Turbo C++ the purpose of the object file is not portability across platforms.

Altri suggerimenti

Object files are collection of 'machine code' (.text), initialized data and symbols, which are to be linked.

A valid object file can contain just data, e.g. bytecode.

A linker is program that maps a whole bunch of objects into a virtual address space and resolves in which address some external symbol belongs to. This allows incremental development of programs, as one only needs to know an interface when calling e.g. the function printf. The linker will inject the real address of the printf inside the machine code in linking stage. This is done with relocation tables.

This partially answers the question #3: one can not directly use an object file created by another architecture. The interfacing method is not necessarily binary compatible. Also the obj -file formats can be different. But if one really puts effort, one can write wrappers (most likely in assembly) that can call objects compiled in Turbo C from Visual C. If the instruction sets and memory models etc. differ completely, one could still write an emulator that calls the function. These kind of approaches are constantly used when writing e.g. video playback frameworks, which can call some legacy video decoder only provided in a .dll.

Linking happens partially also when an OS loads an executable from disk to memory or when a program is linked with 'dynamic libraries'. In those cases one can inject many calls to "printf", but the linker only puts a call to a 'stub', which once called, loads the proper library from the OS and replaces itself with the library function.

The statement #1 is not right enough. Compilers and assemblers convert human readable code to machine code, although some compilers produce intermediate language to be interpreted (and/or 'Just In Time' compiled). In this last stage the compilation really means what it should -- compiling to machine code.

Gcc contains an assembler and linker. One can compile int main() { printf("HelloW\n");} with gcc -S hw.c to assembler (hw.s), which is symbolic machine code, insert or replace some lines and recompile to object code gcc -c hw.s and finally link gcc -o hw.exe hw.o

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top