flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > fasm 64 bit

Author
Thread Post new topic Reply to topic
bzt



Joined: 09 Nov 2018
Posts: 78
bzt 22 Dec 2018, 19:50
Hi,

Is there a 64 bit fasm? I mean I'm well aware that fasm can generate 64 bit, but I'm asking for an assembler running in long mode.

What would be the best way to port it? I don't trust a simple sed s/eax/rax/g would do the trick. Considering that 32 bit registers work just fine in long mode, and small memory model is more than enough (I mean only the first 2G of the entire 64 bit address space is used), then I suppose only push/pop needs to be altered? (Because it's impossible to encode "push/pop reg32" in long mode.) Is it possible to create some macros, overloading 32 bit mnemonics so that would allow vanilla fasm source to be compiled for 64 bit? Or source must be modified and reorganised a bit (what pops into my mind, 32 bit has absolute addressing, but there's only RIP-relative addressing in long mode which may or may not cause trouble)? I know system integration part must be rewritten because the ABI is different, I mean other than that.

What about fasmg? (Sorry, I haven't checked that yet, only used fasm 1 so far). Is it possible to have a 64 bit fasmg? To my understanding fasmg internals are much simpler than fasm, which means it would be a lot easier to port. Am I right? Or maybe with the right macroset it is already possible to compile fasmg's source into a 64 bit executable?

Thanks in advance,
bzt
Post 22 Dec 2018, 19:50
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 22 Dec 2018, 20:25
Here's an earlier thread about this: https://board.flatassembler.net/topic.php?p=203560

Later I also used the same trick to make a 64-bit DLL version of fasm, as mentioned here: https://board.flatassembler.net/topic.php?p=205957#205957 (you can download it from the first post of the thread). But keep in mind that x64 versions made using these tricks do not gain anything from running in long mode. I made 64-bit DLL just so it would be possible to use such library in 64-bit applications.
Post 22 Dec 2018, 20:25
View user's profile Send private message Visit poster's website Reply with quote
bzt



Joined: 09 Nov 2018
Posts: 78
bzt 23 Dec 2018, 03:57
Excellent! How could I miss that? Thank you Tomasz!

Well, I'd say fasm is pretty fast already, so I wasn't looking for better performance. The gain is you can have fasm on purely 64 bit OSes that do not implement compatibility mode and have 64 bit-only libc. I'd say having an assembler which does not utilize all the potential long mode features is much-much better than having nothing at all Smile

Would it be a big thing to ask for an 64 bit libc version on the downloads page? I know having 64 bit version of all downloadables (Win, Linux etc.) would be a big task, but maybe one single fasm.o for 64 bit libc?

Cheers,
bzt
Post 23 Dec 2018, 03:57
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 04 Jan 2019, 17:32
With any libc-dependent version the main problem is malloc - because we cannot rely on it to allocate memory in the accessible addressing space (in the low 4G, that is). With sys_brk we have no such problem, as it simply extends the size of memory block that starts at the program base (which is under our control, defined in ELF header). But malloc may also decide to use a sys_mmap, which can potentially get us a memory in inaccessible range.

Though, maybe in practice it could be reliable enough to just handle it with an "out of memory" error when malloc returns memory in high area. But note that this could potentially lead to confusing situation where you would request just a little amount of memory for fasm and still get "out of memory" because of specifics of malloc implementation on given system.

The exact same problem is what prevented me from making a fasmg.x64 using these tricks. Even the syscall-based version of fasmg still uses a dynamically linked malloc from libc, because unlike fasm 1, fasmg heavily depends on a good malloc+realloc implementation.

A potential solution would be to make fasmg use sys_brk like fasm 1, to just allocate a solid block of memory, and then have my own allocator operating within this block. This is something I have been considering but remains on a "to do" list only.

Other than malloc-related problems, adapting fasmg code to run in long mode could be done with even fewer tricks than in the case of fasm 1. In the fasmg core I have deliberately avoided stack accesses other than top of the stack ([ESP], which in long mode would naturally become [RSP] if we kept binary code unaltered). This means that PUSH/POP instructions could stay mostly unchanged and operate on native 8-byte values instead of 4-byte ones. Where operand to PUSH is a memory, a register like R8D can be used to hold the value and then a natural PUSH R8, with POP the same in the other direction. In fact, as long as we have a malloc implementation that reliably returns memory addressable with 32 bits, fasmg code might run mostly unchanged on binary level, thanks to ingenuity of long mode opcodes that I continue to praise.
Post 04 Jan 2019, 17:32
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 04 Jan 2019, 22:35
PS. You may notice that such "long mode with 32-bit addresses" approach is in fact exactly what x32 ABI is all about. If only it was available in usual environments, it would be exactly what fasm[g] needs. But apparently it is so rare in the wild, that even finding one to test my examples was not easy.
Post 04 Jan 2019, 22:35
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 10 Jan 2019, 21:13
I have finally managed to make fasmg.x64 (a 64-bit ELF executable) with a couple of tricks and a simple malloc implementation contributed by redsock.

Moreover, it has mostly happened live on stream.

The complete sources and fasmg.x64 executable file are now in the official package.

As this is still experimental and requires more testing, a call to "mcheck" is made just before program termination, it scans the entire malloc-managed memory for sign of corruption. If something goes wrong, you are going to receive "Breakpoint/trap" message at exit - please then report the bug to me (possibly with sources that cause it). Later, when I'm convinced that this experimental version is stable enough, I'm going to remove the "mcheck".
Post 10 Jan 2019, 21:13
View user's profile Send private message Visit poster's website Reply with quote
redsock



Joined: 09 Oct 2009
Posts: 430
Location: Australia
redsock 10 Jan 2019, 21:46
Well done, and the watching it come together live was excellent Smile
Post 10 Jan 2019, 21:46
View user's profile Send private message 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.