How to set the alignment for the .data section?
Asked Answered
H

1

6

I defined the following variables in the .data section in NASM:

section .data
    var1       DD   12345    ; int (4 bytes)

    var2       DB   'A'      ; char (1 byte)

    padding1   DB   123      ; 1 byte padding
    padding2   DB   123      ; 1 byte padding
    padding3   DB   123      ; 1 byte padding       

    var3       DQ   174.13   ; double (8 bytes)

In order for these variables to be correctly aligned, the .data section must be aligned to 8 bytes.

I believe that the alignment for the .data section is specified by the linker. I am using the Visual C++ 2010 linker, how can I set the alignment for the .data section using this linker?

Hanshaw answered 25/8, 2017 at 4:10 Comment(2)
Nasm has a directive: nasm.us/doc/nasmdoc4.html#section-4.11.12Persuade
There are also qualifiers you can put on the section directive: nasm.us/doc/nasmdoc7.html#section-7.5.1Persuade
P
8

The align directive works for data as well as code.

In the assembler's output file (an object file in the format the MSVC's linker can understand), it signals the required alignment of each section using metadata.

For example, if you use

section .data
align 1024*1024*2
foo: dd 1234
align 8       ; will assemble to 4 bytes of padding to reach the next multiple of 8
bar: dd 4567

The object file will have its required-alignment for that section set to 2MiB. At least that works on Linux, where I think the section in the object file inherits the highest alignment requirement seen in the source file, so very high alignments are possible.

For win32 object files, NASM even has special syntax for section alignment:
section .data data align=16 like in the example in the manual. The default is align=4 for .data in win32/win64, apparently. The maximum is 64. I don't know if align directives inside a section can increase its alignment if none is specified for -f win32 / -f win64. If not, as the manual cautions, you might be aligning wrt. the start of the section but not in an absolute sense.

ELF object files (Linux) work the same way, with each section having a required-alignment.

Your object file (hopefully) doesn't end up filled with up-to-2MiB of padding, but it might after linking if it links after something else that has a few bytes in a section that goes into the same segment as .data in the executable.

But still, knowing (or setting) the minimum alignment of the start of a section, the assembler can support align directives of any power of 2 at any point in the middle of any section. The align directive doesn't have to be at the start of a section.

Ploughman answered 25/8, 2017 at 20:13 Comment(4)
Just to make sure I understood it: Let's say I don't use align and the .data section starts at address 39995, and then I used align 8, does that mean the .data section will now start at address 40000?Hanshaw
@user8426277: the default alignment is at least 8, maybe 16. But yes, if the default alignment has been only 1, then your example would be exactly what happens.Ploughman
The manual is not 100 % clear, but says: "A final caveat: ALIGN and ALIGNB work relative to the beginning of the section, not the beginning of the address space in the final executable. Aligning to a 16-byte boundary when the section you're in is only guaranteed to be aligned to a 4-byte boundary, for example, is a waste of effort." So afaict, answer is incorrect. Use section .text align=128 to ensure that the section itself is aligned.Abrupt
@BjörnLindqvist: Thanks, updated. The manual says that align=64 is the max supported by the win32 object file format.Ploughman

© 2022 - 2024 — McMap. All rights reserved.