Search code examples
assemblyx86ssememory-alignmentfasm

FASM align 32 section is not aligned enough


im using FASM and this is my program

format ELF64

section '.text' executable

public func

func:
        vmovaps ymm0, YWORD [.table]
        xor     rax, rax
        ret

        align 32
        .table:
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      2048
                DQ      2048
                DQ      2048
                DQ      2048

im using AVX so i created a table (which Must be aligned at 32-Byte Boundary) to initializing the ymm0 register. but when i try to compile this program, i get "section is not aligned enough" error from FASM. ".table" must be aligned at 32-Byte boundary because i am using "movaps" (or movdqa (no matter)). but why FASM gives me an error ? is it wrong to use 'align' like this?

UPDATE is it right to do something like this ? because by doing this, program works without any problem but is it a right way?

section '.text' executable

public func

func:
        vmovaps ymm0, YWORD [.table]
        xor     rax, rax
        ret

        section '.rodata' align 32

        .table:
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      2048
                DQ      2048
                DQ      2048
                DQ      2048

Solution

  • With FASM, alignment inside a section can't be greater than the section alignment itself. When you don't specify a section's alignment the default is 8 for ELF64 and 4 for ELF. To change the default section alignment use align like this:

    section '.text' executable align 32
    

    This should allow you to use alignment up to 32 within the section. Your code could have looked like this:

    section '.text' executable align 32
    
    public func
    public func2
    
    func:
            vmovaps ymm0, YWORD [.table]
            xor     rax, rax
            ret
    
            align 32
            .table:
                    DQ      1024
                    DQ      1024
                    DQ      1024
                    DQ      1024
                    DQ      2048
                    DQ      2048
                    DQ      2048
                    DQ      2048
    
    func2:
            vmovaps ymm0, YWORD [.table]
            xor     rax, rax
            ret
    
            align 32
            .table:
                    DQ      1024
                    DQ      1024
                    DQ      1024
                    DQ      1024
                    DQ      2048
                    DQ      2048
                    DQ      2048
                    DQ      2048
    

    You can put the constant data in the .rodata (read only) separate from code in the .text (code) section. You can have multiple functions using that data. You can place different tables and data and use the align directive inside sections to align specific data that may require it. This code doesn't do anything useful, but is an example:

    FORMAT ELF64
    
    section '.text' executable
    
    public func
    public func2
    public func3
    public func4
    
    func:
            vmovaps ymm0, YWORD [table]
            xor     rax, rax
            ret
    
    func2:
            vmovaps ymm0, YWORD [table2]
            mov     eax, MyStr
            ret
    
    func3:
            vmovaps ymm0, YWORD [table]
            xor     rax, rax
            ret
    
    func4:
            vmovaps ymm0, YWORD [table3]
            xor     rax, rax
    
            ret
    
    section '.rodata' align 32
    
    MyStr: DB 'Hello There', 0
    
    align 32
    table:
            DQ      1024
            DQ      1024
            DQ      1024
            DQ      1024
            DQ      2048
            DQ      2048
            DQ      2048
            DQ      2048
    
    align 32
    table2:
            DQ      1024
            DQ      1024
            DQ      1024
            DQ      1024
            DQ      2048
            DQ      2048
            DQ      2048
            DQ      2048
    
    table3:
            DQ      1024
            DQ      1024
            DQ      1024
            DQ      1024
            DQ      2048
            DQ      2048
            DQ      2048
            DQ      2048
    

    Note: In this example all the table data is the same, but in a real situation tables would have whatever pertinent values you require.