flat assembler
Message board for the users of flat assembler.

Index > Linux > [AMD64] HOWTO: Mix c++ (GCC) and FASM

Author
Thread Post new topic Reply to topic
Nikso



Joined: 20 Oct 2003
Posts: 9
Location: Italy
Nikso 08 Oct 2006, 10:52
Hi there!

So I needed to mix asm and c++ under Linux for 64 bit OS development.
As you may know, in an AMD64 environment GCC use ABI 0.98 specification (see here). This means that parameters are no longer passed thru the stack but registers are used instead.

NOTE: this example is not complete yet. I was not able to refer exported variables (look at commented lines in the code)

AsmPart.asm
Code:
; Writed for board.flatassembler.net by Nikso

; CppAndAsm
;
; x86-64 GCC calling convention (ABI 0.9Cool
;   GCC will use the following register (in order) for parameters passing:
;   RDI, RSI, RDX, RCX, R8, R9, (stack)
;   this is true only if the parameter fit in a register.
;   Return registers are: RAX, RDX
;   For more informations: http://www.x86-64.org/documentation

format ELF64 

section '.text' executable

; void write(char*)
extrn "_Z5writePc" as write

; int sum(int a, int b)
public sum
sum:
        MOV EAX,EDI
        ADD EAX,ESI
;???    ADD EAX,[num]
        
        PUSH RAX
        MOV EDI,strg
        CALL write
        POP RAX
        
        RET




section '.data' writeable

extrn "num" as num
;public strg
strg DB "everything!",0
    

Compile with:
Code:
fasm AsmPart.asm AsmPart.o    


CppPart.cpp
Code:
// Writed for board.flatassembler.net by Nikso

#include <iostream>

using namespace std;

extern "C" int sum(int a, int b);

//extern char* strg;

int num = 10;

void write(char* cosa)
{
        cout << "Calculate within ASM " << cosa << endl;
}

int main()
{
//      cout << strg << endl;
        cout << "2 + 3 = " << sum(2,3) << endl;
        return 0;
}
    

compile with:
Code:
gcc -o CppPart.o -c CppPart.cpp    


Now link with:
Code:
gcc -o cppandfasm AsmPart.o CppPart.o    



In the attached archive there are sources, makefile, binary and the GCC asm compilation of the cpp file.

Hope this help!
Bye Very Happy


Description: Mix FASM and c++ with sourcefile and makefile
Download
Filename: CppAndFasm.tar.bz2
Filesize: 6.27 KB
Downloaded: 873 Time(s)

Post 08 Oct 2006, 10:52
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 08 Oct 2006, 11:22
great, thanks.

how did you come to "_Z5writePc" decoration?

i found going back from stack to registers stupid... :/
Post 08 Oct 2006, 11:22
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Nikso



Joined: 20 Oct 2003
Posts: 9
Location: Italy
Nikso 08 Oct 2006, 11:40
Ah yeah, nice question.
Well there is two ways.
First you can compile CppPart.cpp with:
Code:
gcc -S -c CppPart.cpp
    

This will produce a .s file that you can inspect with a text editor.

Or you can use this command:
Code:
$ nm CppPart.o | grep <func_name>
    

nm will list symbols of the specified object.
Try also:
Code:
$ nm <.o_file> | grep <func_name> | c++filt
    

to look at human readable symbols (useful in case of function overloads)
IE:
Code:
$ nm CppPart.o | grep write
000000000000006c T _Z5writePc
$ nm CppPart.o | grep write | c++filt
000000000000006c T write(char*)
    
Post 08 Oct 2006, 11:40
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
mattst88



Joined: 12 May 2006
Posts: 260
Location: South Carolina
mattst88 10 Oct 2006, 22:47
I know how to pass integers back and forth, but returning floating point numbers is getting the best of me.

The ABI says that xmm0 and xmm1 are used for returninf floating point numbers, but can someone give me an example?
Post 10 Oct 2006, 22:47
View user's profile Send private message Visit poster's website Reply with quote
mattst88



Joined: 12 May 2006
Posts: 260
Location: South Carolina
mattst88 12 Oct 2006, 01:55
Is the high quadword or low quadword used for passing a double? Or is the double duplicated throughout both quadwords?

I've been doing some tests and the results I've been getting are completely unexplainable. Sometimes, it'll return the value, other times not. Sometimes in the high quadword, others in the low. I've even gotten it to return 0.0 if both quadwords are 0.0, and -0.0 if the low quadword is 0.0 and the high undefined.

wtf is going on? Could someone be kind enough to give me an example?
Post 12 Oct 2006, 01:55
View user's profile Send private message Visit poster's website Reply with quote
Mark Larson



Joined: 04 Nov 2006
Posts: 13
Mark Larson 08 Nov 2006, 20:16
I haven't gotten floating point working either ( was trying with printf()). However I did notice one other thing.

you MAY need to set rax up according to the ABI. It is supposed to contain the number of floating point parameters you are passing to the function if the function takes a variable number of parameters. From the 0.98 version of the ABI:

"with variable arguments passes information about the number of SSE registers used"

_________________
BIOS programmers do it fastest! Wink
Post 08 Nov 2006, 20:16
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.