flat assembler
Message board for the users of flat assembler.

Index > Linux > First steps to convert Win projects to Linux

Author
Thread Post new topic Reply to topic
donn



Joined: 05 Mar 2010
Posts: 321
donn 10 Feb 2020, 23:21
Hi, I'm sure this has been asked in some form before, but have not found an answer yet via search.

I'm trying to convert two 64-bit Win projects to be able to run on Linux. They only call ~10 external functions: HeapAlloc, GetProcessHeap, CreateFile, and similar. Following fasmg's lead, I'll use malloc and the related calls in fasmg.asm.

First question: Since I'm trying to follow proper calling conventions, I pass rcx, rdx, r8, r9 into calls, even internally, in that order. In Agner's calling conventions doc, I see these same registers are used as Linux parameters. When calling internal functions, is there anything wrong with using these same registers but in the Windows order, just to get things running? The projects are a bit to far along to wrap internal calls in procedure call macros, and I looked at heavyThing to see what conventions it used. Seems like it passes in registers using the Linux convention order on internal calls also.

Second question: Less importantly, but since I'm using fasmg with these projects, is there a way to replace these existing Windows-style callee-preserved blocks with a macro:

Code:
        push rbx 
        push rbp 
        push rdi 
        push rsi
        push rsp 
        push r12 
        push r13 
        push r14 
        push r15    



so I can replace them with the Linux side? Not as important since I can figure this part out with time, not stuck on this. Figured escaping is probably involved, and still learning the rules.

Much appreciated.
Post 10 Feb 2020, 23:21
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20481
Location: In your JS exploiting you and your system
revolution 10 Feb 2020, 23:43
For calling conventions you can use whatever you are comfortable with, in Linux or Windows. You only need to conform the the platform conventions when you call the OS APIs.

So in Windows you have fastcall to call the system DLLs, and in Linux you have the System Call convention to call OS. Everything else makes no difference within your own code.

For macros you can do this:
Code:
macro save_it_all {
        push rbx 
        push rbp 
        push rdi 
        push rsi
        push rsp 
        push r12 
        push r13 
        push r14 
        push r15
}
;...
save_it_all    
Post 10 Feb 2020, 23:43
View user's profile Send private message Visit poster's website Reply with quote
donn



Joined: 05 Mar 2010
Posts: 321
donn 11 Feb 2020, 14:33
Great and great. I'll use a macro like that, seems like the most efficient approach.
Post 11 Feb 2020, 14:33
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20481
Location: In your JS exploiting you and your system
revolution 11 Feb 2020, 14:37
Note that push and pop themselves allows this syntax:
Code:
push rbx rbp rdi rsi rsp r12 r13 r14 r15    
Post 11 Feb 2020, 14:37
View user's profile Send private message Visit poster's website Reply with quote
donn



Joined: 05 Mar 2010
Posts: 321
donn 11 Feb 2020, 17:02
New fasmg supports this now, right? On version g.i4pue I get:

Code:
1>      push rbx rbp rdi rsi rsp r12 r13 r14 r15
1>  macro push [1] macro push_instruction [1] macro parse_operand [7] macro parse_operand_value [32]:
1>      ns.imm = +op
1>  Processed: @src.imm = +rbx rbp rdi rsi rsp r12 r13 r14 r15
1>EXEC : error : extra characters on line.    


On the newest version, the horizontal push assembles I believe, but am getting this:

Code:
1>------ Build started: Project: datap, Configuration: Release x64 ------
1>Build started 2/11/2020 11:51:13 AM.
1>InitializeBuildStatus:
1>  Touching "x64\Release\datap.unsuccessfulbuild".
1>PreBuildEvent:
1>  flat assembler  version g.itvp8
1>  ..\src\main\asm\datap.asm [10] ..\src\main\asm\datap.inc [3] ..\src\main\asm\Includes.inc [2] ..\src\main\asm\Include/List.inc [1] ..\src\main\asm\Include/../List/List.inc [515]:
1>      je getNextItem.retrieveFromFirstItem
1>  je [2] parse_jump_operand [25] parse_operand [38] (CALM)
1>EXEC : error : symbol 'retrieveFromFirstItem' is undefined or out of scope.    


I attached this file. It built successfully on the version g.i4pue as you can see here: Azure CI Pipeline build or here without JS: CI log plain text
I also uploaded an attachment of this file, maybe there is a breaking change?

The line:
Code:
        je getNextItem.retrieveFromFirstItem    


Description:
Download
Filename: List.inc
Filesize: 56.18 KB
Downloaded: 813 Time(s)

Post 11 Feb 2020, 17:02
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20481
Location: In your JS exploiting you and your system
revolution 11 Feb 2020, 17:21
Use fasm.
Post 11 Feb 2020, 17:21
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8361
Location: Kraków, Poland
Tomasz Grysztar 11 Feb 2020, 17:28
donn wrote:
I also uploaded an attachment of this file, maybe there is a breaking change?
Since then, I changed fasmg to be more compatible with fasm 1 with regards to symbols starting with dot. You have a definition that looks like this:
Code:
list.getNextItem:
; ...
        .retrieveFromFirstItem:    
With early fasmg releases "list.getNextItem:" label did not become the parent symbol for subsequent labels starting with dot, because it is in a different namespace than the current one. This was incompatible with fasm 1, which would use "list.genNextItem" as a new parent, so that the ".retrieveFromFirstItem" would define "list.genNextItem.retrieveFromFirstItem". This incompatibility was a bit confusing, so later I modified fasmg to behave the same as fasm 1 and always update "current parent" when the label does not start with a dot.

PS. Perhaps you missed my note in other thread where I told you about this exact change.
Post 11 Feb 2020, 17:28
View user's profile Send private message Visit poster's website Reply with quote
donn



Joined: 05 Mar 2010
Posts: 321
donn 11 Feb 2020, 20:35
Oh, I saw it and think I understand now. The first thing I was trying to figure out was why
Code:
list.getNextItem:    ; This begins function body    

and
Code:
namespace list
getNextItem:
namespace getNextItem    
were not the same. There are some things you take for granted when using namespaces, like labels not switching the namespace, and I just had to try out a few variations to make sure I got it.
I also was curious if there would be any differences with referencing namespaces outside the current namespace i.e. a function body calls an outer function, and was just able to successfully compile a few examples of this, simple branching, and nested namespaces using both assembler versions.

Think I'm squared away, just had to put in a bit more time 'hands on' since sometimes questions lead to more questions. Just a matter now of benefits gained from each style and refactoring effort.

namespace is my favorite feature of newer fasm(g) versions, so I'll definitely try to keep upgrading.
Post 11 Feb 2020, 20:35
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.