flat assembler
Message board for the users of flat assembler.

Index > Main > How do you track register usage in your source code?

Author
Thread Post new topic Reply to topic
sylware



Joined: 23 Oct 2020
Posts: 513
Location: Marseille/France
sylware 15 Jan 2026, 12:02
MeMeMe: I use a C pre-processor to avoid my code to be too much tied to the pre-processor of a specific assembler (that's why I wonder if RFC-izing fasm CALM/macro would not be not be a good end game solution since it is a sweet spot which allows generic assembler writting AND file format support up to the complexity of PE+ and ELF64).

It allows me to name registers and to perform simple recursive text transforms (nested namespaces/labels).

For each significant (very mood dependent) code section, I have a pre-processor prolog where I define what I have "globally" (all "dominators" code sections), on "entry" (from each specific branching/fall-thru to this code section), and finally the various register names for the code section itself. After the code section I have an epilog where I do undefined everything. I build "entry" definitions based on the related "dominator" code section definitions.


(I use vim folds for that which naturally provides a one-liner visual boundary, in order to avoid too much scrolling)

I only take care of the register mapping once I have written a satifying version of a code section


And you? How are you handling it?
Post 15 Jan 2026, 12:02
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1757
Location: Toronto, Canada
AsmGuru62 15 Jan 2026, 12:47
So, the register renaming is done to improve readability of code?

I name my registers as EAX, EBX, etc. -- just as Intel named them.
I also design my functions to be short -- well, 95% of them.
So, it is not a big deal to see how register is used.

In addition the IDE has the ability to track usage of a token:
- I right click on a register name, say: "r8d" and select a menu item "Find token in procedure".
- IDE looks if the caret line is within "proc"/"endp" lines, and if so:
- IDE lists (in a search panel) all lines where "r8","r8w","r8d","r8b" shows up.
Post 15 Jan 2026, 12:47
View user's profile Send private message Send e-mail Reply with quote
sylware



Joined: 23 Oct 2020
Posts: 513
Location: Marseille/France
sylware 15 Jan 2026, 15:05
@AsmGuru62, you went the "very short" function way. In other words, "a lot of functions" way. Then you track what does your program mostly with function names and their parameter names, I see.

If I were to port my code from my side to yours, I guess most "code sections" would become "very short functions".

That said, do you have "your own internal ABI"? Because following an official ABI with a reasonably deep call graph will imply significantly more register saving on the stack. Or you do things another way?
Post 15 Jan 2026, 15:05
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1757
Location: Toronto, Canada
AsmGuru62 15 Jan 2026, 16:58
I do not have an ABI, wait... what is ABI?
Lot of functions are Okay, because everything is an object, and every object has functions to work with its internal data, below is an example.
Imagine you have a structure like this:
Code:
; ---------------------------------------------------------------------------
; FILE: String.Inc
; DATE: January 15, 2026
; ---------------------------------------------------------------------------
struct CStr
    Flags       db ?
    Length      db ?
    Buffer      rb 254
ends
    

And then, you have a set of functions which prefixed with the name, identifying the object:
Code:
; ---------------------------------------------------------------------------
; FILE: String.Asm
; DATE: January 15, 2026
; ---------------------------------------------------------------------------
align 16
proc String_Init pChar:DWORD
; ---------------------------------------------------------------------------
; Input:
;   ebx = pointer to CStr object
; ---------------------------------------------------------------------------
    ret
endp

align 16
proc String_InitWithLen pChar:DWORD, Length:DWORD
; ---------------------------------------------------------------------------
; Input:
;   ebx = pointer to CStr object
; ---------------------------------------------------------------------------
    ret
endp

align 16
proc String_Concatenate uses esi edi, pCStr:DWORD
; ---------------------------------------------------------------------------
; Input:
;   ebx = pointer to CStr object
; ---------------------------------------------------------------------------
    ret
endp
    

And, then, you have another object:
Code:
; ---------------------------------------------------------------------------
; FILE: Vector.Inc
; DATE: January 15, 2026
; ---------------------------------------------------------------------------
struct CVector
    Count       dd ?    ; # of items stored into 'Array'
    Room        dd ?    ; # of items reserved in 'Array'
    GrowBy      dd ?    ; # of items to grow in 'Array' if 'Count' is about to exceed 'Room'
    Array       dd ?    ; array of DWORD values (pointers, values, etc.)
ends
    

And, now, I will reuse the names used in CStr object:
Code:
; ---------------------------------------------------------------------------
; FILE: Vector.Asm
; DATE: January 15, 2026
; ---------------------------------------------------------------------------
align 16
proc Vector_Init nGrow:DWORD
; ---------------------------------------------------------------------------
; Input:
;   ebx = pointer to CVector object
; ---------------------------------------------------------------------------
    ret
endp

align 16
proc Vector_Add item:DWORD
; ---------------------------------------------------------------------------
; Input:
;   ebx = pointer to CVector object
; ---------------------------------------------------------------------------
    ret
endp

align 16
proc Vector_Concatenate pCVector:DWORD
; ---------------------------------------------------------------------------
; Input:
;   ebx = pointer to CVector object
; ---------------------------------------------------------------------------
    ret
endp
    

Having a lot of small functions is a good thing if they are properly named.
Post 15 Jan 2026, 16:58
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20825
Location: In your JS exploiting you and your system
revolution 15 Jan 2026, 17:03
Quote:
Code:
ebx = pointer to CVector object    
That is the ABI. Defining which registers are used for what purposes.
Post 15 Jan 2026, 17:03
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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.