How to compile assembly language in c - c

I am looking at lots of assembly language code that is compiled along with c. They are using simple #define assembly without any headers in boot.s code. How does this work ?

Typically .s files are processed by an assembler. Without knowing any other details, there's nothing more to say. .s file goes in, .o file comes out.
Many assemblers provide some kind of include directive to allow use of headers, which would also be in assembly language.
Ah, the code you linked is for use by the GNU as assembler. If you're on Linux or Mac, do man as to learn about it. If you're on Windows, install MinGW or Cygwin.

Compilers can frequently include in-line assembly, but I believe it is compiler specific.
I don't remember the precise details, but I think its something like:
void myFunc(void)
{
int myNum; /* plain old C */
__asm /* Assembly */
{
mov ax,bx;
xor cx,cx;
}
myNum = 5; /* more C */
}
Research your specific compiler for details.

The link you post in your comment is an assembly language source file that is meant to be first run through a c-preprocessor. It's just a programming convenience, but lots of assembly language compilers support similar constructs anyway, so I'm not sure why they went the c-preprocessor route.

If you have "main proc" inside of your code, you are using x86 architecture and your file ends with .asm you con use for compilation:
tasm fileName.asm
In result you will get your fileName.obj file. After that you need to link it and for
that you can use tlink filename.obj
To run, just enter the filename.exe on the command line
If you need to link more than one file use tlink filename1.obj filename2.obj and so on
during the compilation and linking is not necessary to specify the file extension like .obj or .asm. Using just filename should be fine.

Related

How to write inline Assembly with Turbo C 2.01?

I want to write some inline assembly in a DOS program which is compiled using Turbo C 2.01. When I write
asm {
nop
}
the compiler claims that in-line assembly is not allowed in function .... See:
Any ideas?
See the Turbo C user manual page 430:
Inline assembly not allowed
Your source file contains inline assembly language statements and you are compiling it from within the
Integrated Environment. You must use the TCC command to compile this
source file.
I believe that you need also to pass the -B option to TCC (page 455).
Alternatively you can use __emit__ (page 103) for relatively simple code entered as machine code rather than assembler mnemonics.
It seems an odd restriction to not allow inline assembly in the IDE. You might consider "upgrading" to Turbo C++ 3.0 which I believe does allow it. I would imagine that TC++ will compile C code when presented with a .c file, or that the IDE can be set to compile C explicitly. There's a manual for that too.
Turbo C converts C code directly into machine code without using an assembler phase, and thus cannot include assembly language source within a program. What it can do, however, is use the __emit directive to insert machine code. The cleanest way to use that is probably to use a separate assembler (or perhaps DEBUG) to process the code of interest by itself into a COM file, and then enter the byte values therein into an __emit directive. Parameters are stored in ascending order left to right, starting at either BP+4 (in tiny, small, or compact model) or BP+6 (medium, large, or huge). Local variables are stored at addresses below BP.
When using Turbo Pascal, it's possible to use a handy program called "inline assembler" to convert assembly-language source into a Turbo Pascal literal-code directive. Turbo Pascal's directive is formatted differently from C's (I like Pascal's better) and can accommodate labels in ways Turbo C's cannot. Still, using __emit may have far less impact on build times than trying to use inline assembly code.

Can you add preprocessor directives in assembly?

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.

How to modify existing assembly code generated from C

I'm writing some methods in C that must run very efficiently, so I'd like to manually edit some of the assembly code that is automatically generated.
I know how to read the assembly code using gdb or "objdump -d myfile.o", but can anyone tell me how to edit this code? (Will probably just be minor tweaks.)
gcc have -S switch, which stops compilation on after assembly generation phase. Then you cound edit resulting file and manually call assembly (with gas, for example)
Sure. It's called "inline assembly", and most compilers support it.
Here's an example using GCC:
http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
There's no way you can do it.
Compiler generates code directly, there is no assembler involved; assembly listing is an aux product that can be generated, can be not.
You can take asm listing and assemble it yourself, however.
If you want to improve efficiency of your code, the best way to follow is, as stated before, inline asm; or write an assembly proc, make an object file and link it.

How to tell what version of Intel compiler was used to compile binary

So it is relatively straightforward to tell from the symbols embedded in an executable if an Intel compiler was used to compile it, e.g. from the presence of symbols like __intel_proc_init in the executable.
Is there a way to tell what version of the Intel compiler was used to compile the binary using similar diagnostics?
So I think I figured out a partial answer to my own question. Using the strings utility, I was able to extract the following strings from the Fortran executable:
#(#)Intel Fortran RTL Message Catalog V10.1-101 01-Aug-2007
from another Fortran executable, I found the following strings:
/opt/intel/Compiler/11.1/073/bin/intel64/ifort
#(#)Intel Fortran RTL Message Catalog V11.1-107 16-Mar-2010
however, I was not able to extract any such string from C compiled executables.
PEID is able to do this for MSVC binaries, so you may want to check it out and see if it works for intel, if so then you'd need to find out from the makers what they scan for in the PE/obj dump (iirc some of the info is in plain text in the PE)
The following Fortran source code will output the Intel compiler version at run-time. Obviously similar code in other languages.... Will that meet your need? If not, it might give a clue to a symbol in the executable.
#ifdef __INTEL_COMPILER
write (*, 1050) __INTEL_COMPILER
1050 format ( "Fortran code compiled with Intel ifort, version ", I0 / )
#endif

Using another assembler (MASM, NASM, TASM, etc.) with GCC

I've been looking through questions on here and the internet for a while now and I cannot seem to find out whether or not it is possible to do inline assembly with GCC using something other than GAS. I am trying to find if I can avoid using not only GAS's AT&T syntax (though, I know how to use Intel syntax with GAS) but the extended asm format. While this is not for a project or anything other than my own curiosity, I would really appreciate any help I can get (this is actually my first question here because I could not find an answer about it)! Also, if this makes any difference, I'm currently using DevC++ (for C code, not C++) on Windows.
Thanks,
Tom
You can link the output from an assembler (a ".o" or ".obj" file) with your C or C++ program. Put your assembler code in a text file. Your IDE or makefile will assemble it just as it would any c source file. The only tricky bit is learning how to interface between the two different systems.
You cannot use another inline assembly syntax with GCC. inline assembly is implemented by GCC literally including the assembly you write inline with its own (textual) assembly output, which it then sends to gas to be assembled. Since GCC doesn't know how to change the format of its own output to feed to another assembler, you can't change the inline assembly, either.

Resources