Can you add preprocessor directives in assembly? - c

I would like to execute some assembly instructions based on a define from a header file.
Let's say in test.h I have #define DEBUG.
In test.asm I want to check somehow like #ifdef DEBUG do something...
Is such thing possible? I was not able to find something helpful in the similar questions or online.

Yes, you can run the C preprocessor on your asm file. Depends on your build environment how to do this. gcc, for example, automatically runs it for files with extension .S (capital). Note that whatever you include, should be asm compatible. It is common practice to conditionally include part of the header, using #ifndef ASSEMBLY or similar constructs, so you can have C and ASM parts in the same header.

The C preprocessor is just a program that inputs data (C source files), transforms it, and outputs data again (translation units).
You can run it manually like so:
gcc -E < input > output
which means you can run the C preprocessor over .txt files, or latex files, if you want to.
The difficult bit, of course, is how you integrate that in your build system. This very much depends on the build system you're using. If that involves makefiles, you create a target for your assembler file:
assembler_file: input_1 input_2
gcc -E < $^ > $#
and then you compile "assembler_file" in whatever way you normally compile it.

Sure but that is no longer assembly language, you would need to feed it through a C preprocessor that also knows that this is a hybrid C/asm file and does the c preprocessing part but doesnt try to compile, it then feeds to to the assembler or has its own assembler built in.
Possible, heavily depends on your toolchain (either supported or not) but IMO leaves a very bad taste, YMMV.

Related

Changing preprocessed values during compile time

I have written some code using pre processor directives to skip some statements to be executed.But My C code inside main is interested to change previously #defined values and assign new values as per condition and also change the result of pre processed statements too during run time.In short I have to change the pre processed statements during run time. How can I do this?
In short I have to change the pre processed statements during run time
This is impossible. Read about C preprocessing & cpp. Compile-time and run-time are different (and the compiled code could even run on a different machine, read more about cross-compiling). If using GCC, use gcc -C -E foo.c > foo.i to preprocess your foo.c source file into foo.i preprocessed form (and then use an editor or a page to look inside that generated foo.i)
Perhaps you want to load additional code at runtime. This is not possible with pure C99 standard code. Perhaps your operating system offers dynamic loading. POSIX specifies dlopen. You might also want to use JIT compiling techniques to construct machine code at runtime, e.g. with libraries like GCCJIT, asmjit, GNU lightning, libjit, LLVM, ...
Read also about homoiconic languages. Consider coding in Common Lisp (e.g. with SBCL).
Perhaps you want to customize your GCC compiler with MELT.
Not possible. Preprocessing happens before compile-time.
The compiler only sees the result of the preprocessor, nothing more.

Which file is generated after preprocessing of a C program?

For a C program just before compilation, i.e. after the pre-processing has been completed which file(what extension) is generated?
It is compiler dependent. Most compilers by default don't generate intermediate pre-processor files.
With gcc, if you add -save-temps option to get the intermediate files, the output of the pre-processor is dumped in a .i file. With -E option (to perform only the pre-processing), without -o to specify the output file, the result is dumped to stdout.
In most current compilers (e.g. GCC or Clang/LLVM) - and for performance reasons - the C/C++ preprocessor is an internal part of the compiler (in GCC it is libcpp/ and is a library ...), so no preprocessed form is output into a file.
In the very first C or proto-C compilers (1970s PDP-8) the memory was so small (64kilobytes!) that such an organization was not possible, and the preprocessor was a separate program /lib/cpp
Today, our laptops have several gigabytes of memory, which is usually much larger than the preprocessed form (of the largest source file you'll feed to your compiler). So current compilers keep some internal representation of the whole translation unit and are able to optimize it entirely (inter-procedural optimizations, including inlining).
All compilers keep several forms of the abstract syntax tree (AST); the bulk of the work of a compiler is not parsing or code generation, but transforming some internal representation of the AST into another internal representation (itself further transformed). In GCC most of the optimizations are working on the GIMPLE form. You can extend the compiler by adding your own optimization passes, e.g. with your GCC plugin.
In turn, this technological evolution has fertilized the (evolution of) the definition of our programming languages, recent C++11 is designed for a very optimizing compiler. The recent style guiding or coding hints around C++11 are presupposing (and makes sense only because of) very powerful optimizations.
You still can usually invoke the compiler to spit the preprocessed form, e.g. with gcc -C -E source.c > source.i, in a seperate file (conventionally suffixed .i or .ii, and such suffixes can be known to builder like make)
Journey of a C Program to Linux Executable in 4 Stages :
Pre-processing
Compilation
Assembly
Linking
Check this link for more details C program compilation process
>gcc -E fname.c >fname.x /fname.x is the pre-processed output to which u r saving/
The following four things happen in the pre-processing stage.
1> header file inclusion
2>comment removal
3>macro substitution (eg if u have #fenine NUM 10, where-ever in code you have used NUM ll be replaced by 10)
4> conditional compilation (eg
#if 0
...
some code
...
#endif
since "#if 0" evaluates to 0, the code under it never executes. Therefore code under it is not included in your pre-processed output

Understanding Make in C

I am a seasoned developer in Java and I had learned C in my College days, however I am brushing up my C skill and am following a tutorial from Here
I am trying to follow a tutorial on makefile here is what the author says:
Does the file ex1 exist already?
No. Ok, is there another file that starts with ex1?
Yes, it's called ex1.c. Do I know how to build .c files?
Yes, I run this command cc ex1.c -o ex1 to build them.
I shall make you one ex1 by using cc to build it from ex1.c.
But I am unable to grasp, what is a makefile and why is it used? What are the parameters to the same? Also what are CFLAGS? What is CC? I am new to Ubuntu although.
Good explanation would be very long.
Short explanation: makefile is a set of instructions on how to compile / build an executable. It includes all relationships. For example, "executable A needs object files B and C. B is compiled from files X.c X.h Y.c and Y.h; C depends on K.c". Now if someone modifies K.c, you know you need to recompile C but you don't need to recompile B (just link B and C into A at the end).
As projects get more complicated this becomes more important.
As for flags - there are all kinds of ways to control your compiler. Sometimes you will want to change these - say, you want to include more debug, or increase level of optimization; or change the target architecture. All these things are controlled with flags. By setting a variable to contain these flags, you can replace the flags in many commands at the same time.
You can even change what compiler you want to use - you might have different ones as your source code might contain more than one language (mixtures of C and FORTRAN are still encountered in many numerical analysis libraries, for example.)
cc is a C compiler. So is gcc (the Gnu C Compiler). Other compilers include g++ (for C++), g77 (for FORTRAN77), etc...
All of this means that using a makefile is great for maintaining control and flexibility when compiling large and complex projects.
But really - you need to read up about this properly and not rely on something that was written late at night...

Extending the C preprocessor to inject code

I am working on a project where I need to inject code to C (or C++) files given some smart comments in the source. The code injected is provided by an external file. Does anyone know of any such attempts and can point me to examples - of course I need to preserve original line numbers with #line. My thinking is to replace the cpp with a script which first does this and then calls the system cpp.
Any suggestions will be appreciated
Thanks
Danny
Providing your modified cpp external program won't usually work, at least in recent GCC where the preprocessing is internal to the compiler (so is part of cc1 or cc1plus). Hence, there is no more any cpp program involved in most GCC compilations (but libcpp is an internal library of GCC).
If using mostly GCC, I would suggest to inject code with you own #pragmas (not comments!). You could add your own GCC plugin, or code your own MELT extension, for that purpose (since GCC plugins can add pragmas and builtins but cannot currently affect preprocessing).
As Ira Baxter commented, you could simply put some weird macro invocations and define these macros in separate files.
I don't exactly guess what precise kind of code injection you want.
Alternatively, you could generate your C or C++ code with your own generator (which could emit #line directives) and feed that to gcc

Do I need to compile the header files in a C program?

Sometimes I see someone compile a C program like this:
gcc -o hello hello.c hello.h
As I know, we just need to put the header files into the C program like:
#include "somefile"
and compile the C program: gcc -o hello hello.c.
When do we need to compile the header files or why?
Firstly, in general:
If these .h files are indeed typical C-style header files (as opposed to being something completely different that just happens to be named with .h extension), then no, there's no reason to "compile" these header files independently. Header files are intended to be included into implementation files, not fed to the compiler as independent translation units.
Since a typical header file usually contains only declarations that can be safely repeated in each translation unit, it is perfectly expected that "compiling" a header file will have no harmful consequences. But at the same time it will not achieve anything useful.
Basically, compiling hello.h as a standalone translation unit equivalent to creating a degenerate dummy.c file consisting only of #include "hello.h" directive, and feeding that dummy.c file to the compiler. It will compile, but it will serve no meaningful purpose.
Secondly, specifically for GCC:
Many compilers will treat files differently depending on the file name extension. GCC has special treatment for files with .h extension when they are supplied to the compiler as command-line arguments. Instead of treating it as a regular translation unit, GCC creates a precompiled header file for that .h file.
You can read about it here: http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
So, this is the reason you might see .h files being fed directly to GCC.
Okay, let's understand the difference between active and passive code.
The active code is the implementation of functions, procedures, methods, i.e. the pieces of code that should be compiled to executable machine code. We store it in .c files and sure we need to compile it.
The passive code is not being execute itself, but it needed to explain the different modules how to communicate with each other. Usually, .h files contains only prototypes (function headers), structures.
An exception are macros, that formally can contain an active pieces, but you should understand that they are using at the very early stage of building (preprocessing) with simple substitution. At the compile time macros already are substituted to your .c file.
Another exception are C++ templates, that should be implemented in .h files. But here is the story similar to macros: they are substituted on the early stage (instantiation) and formally, each other instantiation is another type.
In conclusion, I think, if the modules formed properly, we should never compile the header files.
When we include the header file like this: #include <header.h> or #include "header.h" then your preprocessor takes it as an input and includes the entire file in the source code. the preprocessor replaces the #include directive by the contents of the specified file.
You can check this by -E flag to GCC, which generates the .i (information file) temporary file or can use the cpp(LINUX) module specifically which is automatically used by the compiler driver when we execute GCC.
So its actually going to compile along with your source code, no need to compile it.
In some systems, attempts to speed up the assembly of fully resolved '.c' files call the pre-assembly of include files "compiling header files". However, it is an optimization technique that is not necessary for actual C development.
Such a technique basically computed the include statements and kept a cache of the flattened includes. Normally the C toolchain will cut-and-paste in the included files recursively, and then pass the entire item off to the compiler. With a pre-compiled header cache, the tool chain will check to see if any of the inputs (defines, headers, etc) have changed. If not, then it will provide the already flattened text file snippets to the compiler.
Such systems were intended to speed up development; however, many such systems were quite brittle. As computers sped up, and source code management techniques changed, fewer of the header pre-compilers are actually used in the common project.
Until you actually need compilation optimization, I highly recommend you avoid pre-compiling headers.
I think we do need preprocess(maybe NOT call the compile) the head file. Because from my understanding, during the compile stage, the head file should be included in c file. For example, in test.h we have
typedef enum{
a,
b,
c
}test_t
and in test.c we have
void foo()
{
test_t test;
...
}
during the compile, i think the compiler will put the code in head file and c file together and code in head file will be pre-processed and substitute the code in c file. Meanwhile, we'd better to define the include path in makefile.
You don't need to compile header files. It doesn't actually do anything, so there's no point in trying to run it. However, it is a great way to check for typos and mistakes and bugs, so it'll be easier later.

Resources