flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
16bitPM 27 Mar 2013, 01:13
Hello!
I wrote an assembly-optimized version of a long multiply in 64-bit mode (actually a 256x256-bit multiply modulo a very long number, according to the secp256k1 protocol). A friend was wondering how this assembly file would withstand cross-platform development. That's to say: the calling conventions between Windows and Linux are different! http://en.wikipedia.org/wiki/X86_calling_conventions#x86-64_calling_conventions. Now this is very annoying. I'm quite used to MASM style syntax (or its fork JWASM) which COULD provide a solution via prototyping, but apparently the FASTCALL convention has not been implemented for ELF64 yet. Still, the question remains... because most assemblers don't have this kind of prototyping. I could also duplicate all code and change it according to the calling convention. Swapping registers around is no option since that function is called billions of times and is time-critical. My friend is more a fan of inline assembly in a GCC __asm__ blocks, but as most assembly programmers I have a deep hate towards AT&T style syntax ![]() So the question is... have any of you had experience with this kind of problem before & how to deal with this situation in the best way? |
|||
![]() |
|
ProphetOfDoom 27 Mar 2013, 02:47
I wrote a fasm macro about a year ago that wraps the Linux calling convention. However it's a bit messy, may still have bugs and I can't offer support cos I'm too busy
![]() http://board.flatassembler.net/topic.php?t=14142 |
|||
![]() |
|
16bitPM 27 Mar 2013, 12:19
revolution wrote: Are you asking about calling conventions for the OS? Because you are not forced to use the OS API calling convention for your own functions. Especially for time-critical functions where normal rules tend to get thrown out in favour of a more efficient implementation. The function will be called from a C or C++ program. So, I fear that recompiling the source on Windows will yield another binary which is incompatible because my code assumes the Linux calling convention: void ExSetMult((uint64_t *) a.n, (uint64_t *) b.n, (uint64_t *) result); --> Linux: a.n will be in rdi, b.n in rsi and the pointer to the result will be in rdx --> Windows: rcx, rdi, r8 respectively, *AND* you have to set up a frame BUT, I may have solved the puzzle already: GCC has modifiers to change its behaviour. So I can prototype the functions in my C header as follows: Code: extern "C" void __attribute__ ((sysv_abi)) _ExSetMult(uint64_t *, uint64_t *, uint64_t *); extern "C" void __attribute__ ((sysv_abi)) _ExSetSquare(uint64_t *, uint64_t *); |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.