assemblyx86alignmentmasmsegments

How to set align 64 in ml64.exe?


What is a simplest way to set align 64 for some assembler function code with ml64.exe? Default alignment for _TEXT is 16, so ml64 doesn't allow to set more than 16 in align command. And ml64 doesn't allow to change alignment for _TEXT.

It's possible to create another section/segment, but can we get 64 byte alignment in main _TEXT section?

Is there any solution?

P.S. Solution suggested in answer with _TEXT$FOO works! _TEXT$FOO SEGMENT ALIGN(64) align 64 _TEXT$FOO ENDS

I also tried to change the value in alignment field in Characteristics in section header for _TEXT in obj (coff) file in hex editor. And the linker used that changed alignment. So why ml and jwasm don't allow to change that default 16 bytes for _TEXT, if linker can use any value from that field in obj file?

64-byte alignment is useful for code in some cases. If you use 16-bytes alignment, then another code (it can be C code) can randomly move your asm code for 4 different offsets: 0, 16, 32, 48. And some loops probably can cross 64-bytes or 32-bytes range. So you can see some unpredictable changes of performance of asm code , when you just change another C code.


Solution

  • As you say, apparently ml64 (Microsoft Macro Assembler (x64)) doesn't let you change the alignment of the .text section, so you can't have anything in it with an alignment bigger than 16 bytes. However, there's a simple workaround for this problem and that's to use PECOFF's grouped sections feature. If a section has a dollar sign $ in its name then everything after the $ is ignored when linking, so that all sections with the same prefix before the $ are merged into one section. The merged sections are sorted by the full section name, including what comes after the $.

    So for example you can do:

    _TEXT$FOO SEGMENT ALIGN(64)
        int 3
    
        ALIGN   64
        PUBLIC  function
    function:
        ret
    
    _TEXT$FOO ENDS
    
    _TEXT   SEGMENT
        PUBLIC  start
    start:
        call function
        int 3
    _TEXT   ENDS
    
        END
    

    In the example above the _TEXT and _TEXT$FOO sections will be merged into one .text section by the linker. The code in _TEXT$FOO will come after the the code in _TEXT.

    Note that if you're really trying to align readonly data, not actual code, then you should put the data in the .rdata section instead. Something like this:

    _RDATA  SEGMENT ALIGN(64) ALIAS(".rdata") READONLY
        DB  1h
    
        ALIGN   64
        PUBLIC  readonlydata
    readonlydata:
        DB  0ffh
    _RDATA  ENDS
    

    Note that you have to use the ALIAS(".rdata") option here because the assembler doesn't automatically translate _RDATA into .rdata the same way it translates _TEXT and _DATA into .text and .data.