Search code examples
assemblyconventions

Order of procedures in assembly


In what order should asm procedures go in source file: from inner to outer or in reverse? Where should the main code (which is not within proc) go: near the beginning or end of file? Are there objective criteria to choose, not merely convention?


Solution

  • There is no convention; normally put related functions near each other in the source. Basically the same as you would in C or any other language. As far as readability, there's nothing special about asm that overrides this, except that asm functions are usually not very short (because nothing is going to inline them for you, and you don't want actual call/ret overhead all over the place).

    If you're sacrificing performance to get "small functions" for readability, asm is the wrong language; if your project is that big, let a compiler do it. Making a block of code a callable function instead of a macro should be motivated by I-cache footprint and how often it's used.


    Or for performance, group "hot" functions together to they're in the same iTLB page, and even the same L1 instruction cache line for small functions or at boundaries between end of one, start of next. e.g. group together functions that call each other or are often called right after each other.

    If you want source order to be different from binary order, you can put "cold" functions (called once at startup or shutdown) in a section like .text.startup instead of the usual .text section; GCC does this for main for example with this instead of a usual .text directive

    .section        .text.startup,"ax",@progbits
    .globl main
    main:
      ...
    .text            # shorthand for .section .text
    other_function:
    

    ("ax",@progbits for an ELF target means exec permission, and that the section should be mapped into process memory instead of just sitting in the executable on disk without getting mapped by the program loader. Or more specifically, linked into an ELF segment with those properties).

    Try it on Godbolt if you're curious.


    here should the main code (which is not within proc) go

    Huh? Usually you put a label on the entry point even though it's not a "function" per-se. Often you only write a main (which is a function) and let CRT startup code call it.