GCC and functions name mangling
my latest discovery is that gcc in linux does not prepend underscore at the beginning of the names of funcitons, while windows port of gcc compiler does that.
cygwin : gcc -S ble.c
_main: pushl %ebp ... |
linux : gcc -S ble.c
main: pushl %ebp ... |
absence of underscore at the beginning of the name is important when you are trying to use code written and compiled under windows with gcc, or when you write assembler code and compile it with NASM (like in my previous post), this is also way how ive discovered this :) to use function that had been written in assembler and compiled with NASM in my c code (gcc in cygwin, borland) i had to declare it (in asm source) with underscoped name. because both gcc in cygwin and borland expects functions written in c to be preceded with underscore. but when i've tried to compile the same code with gcc under linux i got linker error (underscore)
to use the same assembler code in windows and linux i had to declare function with leading underscore (in linux), or to use
asm() keyword to specify the name to be used in asm code (gcc manual page 281).
i think, the best solution is to add defines so that functions can be imported properly (with underscore) but used in code without it.GCC under linux by default does not add prepend uderscore at the beginning of the function name.
Assembly code in GNU g++
First of all GNU compilers use AT&T assembly syntax, not Intel. Secondly writing inline assembly isnt easy thing to do, especially when you are familiar only with intel syntax. when you need to write function using assembly (for example for complex numbers calculations) there is a better solution, when using inline assembly. As an example i will show sqr function to calculate double number to the power of 2. Assembler code can be seen below, note that doubles are returned via fpu stack
section .text use32 global _sqr _sqr: push ebp mov ebp,esp fld qword [ebp+08h] fmul to st0 pop ebp retassuming that we have saved this code in file fpu.asm, we can compile it using NASM as follows
nasm -f coff fp u.asm (in cygwin)
nasm -f elf fpu.asm (in linux)
this was the first part.. the second is to create code in c++ using our external sqr function, for example:
#include <stdio.h>
extern "C"
{
cpx tst1( const cpx c );
}
int main()
{
double d = 2.0;
printf("%f %f",d,sqr(d));
return 0;
}
to compile this code using g++ compiler we need to pass previously compiled assembler code to the linker.
g++ fpu.o tst.cpp
C++ class in assembler
#include <cstdio> class baseObj { public : int i; baseObj(int o) { i = o + 32; }; }; class childObj : public baseObj { public : childObj(int i):baseObj(i){} }; int main() { baseObj a = childObj(16); a.i += 64; printf("go %d",a.i); };i was expecting (in the time when i was writing this code) compiler to create two functions, that would carry out my constructors. [read more]
Borland inline assembler - once again
and one again about assembler, well about inline assembly language. below we can see differences between pascal and c calling conventions:

ttest test _fnc( ttest z )it will be interpreted as if it was defined as
void test_fnc( ttest *result_ptr, ttest z )so now first argument of function isnt stored under [EBP+08h], where now is placed pointer to return value. pointer is 4bytes long so first argument can be found under [EBP+0ch]. to set up return structure, we will need to use pointer stored in [EBP+08h] to get to the return structure.
if we define the same function in delphi
function test_fnc( z : ttest) : ttestdelphi compiler will treat that function as a procedure of type
procedure test_fnc( z:ttest; var result:ttest )in this case argument of our function will be pointed by EAX register, as we can see result structure of our function is treated as a second argument and EDX register points to it. so if we want to set up result value using assebler, we will just need to use EDX register.
1 , 2 , next (older)