0
.section .data
    align_data:
        .align 4 
        .int 0x11111111, 0x22222222, 0x33333333, 0x44444444
    align_data2:
        .align 2 
        .byte 0x11, 0x22, 0x33, 0x44
    unalign_data:
        .int 0x33333333, 0x44444444
    unalign_data2:
        .byte 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
.section .text
.globl _start
_start: 
    movdqa align_data, %xmm0
    movdqu unalign_data, %xmm1
    movl $1, %eax
    int $0x80

I can't figure out why this error happens. I think I have defined 'align_data' properly with 128-bit size, but when I ran it in gdb, it gives me this:

Program received signal SIGSEGV, Segmentation fault.
_start () at sse.s:15
15      movdqa align_data, %xmm0

If I include mov $0, %ebx in the code, it runs without crashing, but why would that matter?

assembly and linking command:as -g -o sse.o sse.s && ld -o sse sse.o

assembler version: 
GNU assembler version 2.27 (x86_64-redhat-linux) using BFD version version 2.27-43.base.el7_8.1
linker version:
GNU ld version 2.27-43.base.el7_8.1
yyuze
  • 1
  • 2
  • Use `.p2align 4` to align by 2^4, not just 4. You can look at the address in GDB to confirm. Although normally the start of the .data section would be at least 16-byte aligned, I think. Might depend on your `ld` version. – Peter Cordes Mar 13 '21 at 11:26
  • I solved it !!!! I noticed I didn't give EBX a value for INT $0x80 instruction when I post this question. So I add "movl $0, %ebx" before "int $0x80", and it runs normally. But WHY??? – yyuze Mar 13 '21 at 11:26
  • No, that doesn't explain it; leaving EBX untouched would at worst mean you exit with a non-zero exit status (if you made this a dynamic executable), *not* explain a segfault. Your code works fine for me with `gcc -m32 -nostdlib -static foo.s`; this isn't a [mcve], not without an `ld` version and build commands. (But `.align` in GAS for x86 / x86-64 is `.balign`, not `.p2align`, unlike for some other targets. Never use `.align`, pick one of the explicit ones. e.g. I can make it crash by adding `.int 1` *before* the label) – Peter Cordes Mar 13 '21 at 11:30
  • 1
    Oh also, `.align` inserts padding bytes where you put it. You put it *after* the label, so it doesn't change the alignment of the label. (Unlike classic MIPS assemblers where somehow align magically affects the previous label). So anyway, this code only works if `.data` is 16-byte aligned already, the `.align` has zero benefit there and isn't enough alignment anyway. But like I said, it *does* work on my system with ld from Binutils 2.35.1. – Peter Cordes Mar 13 '21 at 11:33
  • @PeterCordes I use "as -g -o sse.o sse.s && ld -o sse sse.o" to produce my executable file. My environment, assembler: GNU assembler version 2.27 (x86_64-redhat-linux) using BFD version version 2.27-43.base.el7_8.1; linker: GNU ld version 2.27-43.base.el7_8.1. – yyuze Mar 13 '21 at 11:39
  • 1
    Ok, interesting that it's apparently not aligning the start of `.data`. And does putting `.p2align 4` in the right place (before the first label) fix it? – Peter Cordes Mar 13 '21 at 11:41
  • @PeterCordes I didn't try .p2align. I put "movl $0, %ebx" before "int $0x80", and fixed.... – yyuze Mar 13 '21 at 11:44
  • 1
    And if you take it out again, that changes the alignment of `.data`, such that you need `.p2align 4` or `.align 16`? Probably just a coincidence of how the bytes are laid out in the object file. Any 5-byte instruction would do the same thing, then, or sequence of things within +/- a few bytes of that. (I'd guess ld itself probably only aligns `.data` by only 4 bytes.) – Peter Cordes Mar 13 '21 at 11:49
  • Also, don't edit your "answer" into the question. Post it separately (so I can downvote it because it merely happens to work by coincidence). Or preferably don't post it at all. – Peter Cordes Mar 13 '21 at 11:51
  • @PeterCordes Thanks for helping and sorry I broke the rule, I m new here. I have tried using '.align 4 .ascii "xxxxx" before, and it dose work. It guided assembler to put 00 byte after the string for aligning it to 8 bytes. – yyuze Mar 13 '21 at 12:01
  • @PeterCordes I checked it using 'objdump -D' command on the executable file – yyuze Mar 13 '21 at 12:02
  • You can verify my claim that your alignment code doesn't work by putting `.byte 1` before `align_data:`. `.align 4` will expand to 0 to 3 bytes, making the address of the thing right *after* it a multiple of 4 (and that doesn't include your load address). That is all, no more and no less. If you got zeros *after* a string from putting `.align` before, then there was another `.align` directive after that, or that was the end of a section. Or you were using a different assembler, like MARS (which behaves like a classic MIPS assembler, *not* like GAS). – Peter Cordes Mar 13 '21 at 12:06
  • @PeterCordes That's true. It dose put 3 zero byte before ```align_data```! – yyuze Mar 13 '21 at 12:15
  • When I do that, I get `align_data` at `0x804a001`. There are 3 bytes of zeros before the first `.int`, because the padding for alignment is *after* the label. (Or did you already apply the fix of moving the `.align` ahead of the label? Then yeah, `.byte 1` / `.balign 4` would emit 3 bytes of zeros) But anyway yeah, `.align` / `.p2align` / `.balign` simply emit padding bytes until the current position has the specified alignment. That's all. – Peter Cordes Mar 13 '21 at 12:17
  • @PeterCordes My tutorial told me to "put ```.align``` before the data defination", guess it is wrong? – yyuze Mar 13 '21 at 12:20
  • Probably, or at least not specific enough. If they showed an example with `label:` `.align` 4; `.int 1, 2,3, 4` then they're explicitly wrong, or were writing for classic MIPS assembler. Either way, look for a a better tutorial, or just think through what exactly needs to happen and look at known-good compiler output, and read the GAS manual. https://sourceware.org/binutils/docs/as/Balign.html#Balign / https://sourceware.org/binutils/docs/as/P2align.html#P2align – Peter Cordes Mar 13 '21 at 12:21
  • @PeterCordes Thank you again! I use ***Professional Assembly Language*** writen by Rechard Blum as my tutorial. It's indeed a very old book, do you have any better tutorial for recomandation? – yyuze Mar 13 '21 at 12:30
  • There are some linked from https://stackoverflow.com/tags/x86/info. I don't know how great any of them are; it's been a couple years since I even reviewed one to see if it was worth linking in the tag wiki. I mostly learned from [looking at GCC output](//stackoverflow.com/q/38552116) to see how it did things, then reading the manuals (ISA manual for instructions, and assembler manual for directives) for things I was curious about. (And of course https://agner.org/optimize/ for performance). Once you know what one thing does, and what the whole thing accomplishes, you can often guess others.. – Peter Cordes Mar 13 '21 at 12:37
  • @PeterCordes GOT IT! – yyuze Mar 13 '21 at 12:39
  • When you say "old book", that still doesn't justify using `.align 4` that way for x86 Linux. I don't think GAS has changed. When I say "classic MIPS", I'm talking about a different CPU architecture (MIPS), with very different software assemblers, like SGI's assembler that came with their IRIX OS. Even GAS for MIPS isn't like that. See [MARS MIPS simulator's built-in assembler aligns more than requested?](https://stackoverflow.com/q/59926448) for more about those classic MIPS assemblers, contrasting it with `clang -target mips` (which is GAS-like). – Peter Cordes Mar 13 '21 at 12:44
  • @PeterCordes Here is the word in the book: "The *gas* assembler supports the *.align* directive, which is used to align defined data elements on specific memory boundaries. The *.align* directive is placed immediately before the data definition in the data section, instructing the assembler to position the data element on a memory boundary." – yyuze Mar 13 '21 at 13:06
  • @PeterCordes In its example whitch used ***.align*** ```.section .data (line break) .align 16 (line break) label ...```.I didn't see it just now (Orz, because it appears in a very latter chapter. – yyuze Mar 13 '21 at 13:13
  • @PeterCordes Maybe it is used for the whole data section alignment? – yyuze Mar 13 '21 at 13:16
  • 1
    Well ok, labels don't take any bytes in the output, so the actual example clarifies that he means before the label you stick on that data as well, and the book hasn't said anything strictly wrong. But like I said, everything follows logically if you understand `.balign 16` as emitting padding at the current location until reaching an alignment boundary. (Because every byte inside a section has to have some value.) – Peter Cordes Mar 13 '21 at 13:24
  • 1
    No, `.align 16` is *not* for the whole data section. Although if the first thing in a section is a `.align` directive, the assembler can just mark the section as needing that much alignment without having to emit any padding bytes. (In fact, it marks the necessary section alignment as max of any alignment you use inside it, so linking / loading respects those directives. If nothing needs more than 4-byte alignment, it can let the start of the section be that weakly aligned. If it ever needs more, it needs to know an aligned starting point.) – Peter Cordes Mar 13 '21 at 13:24
  • @PeterCordes Dose you mean putting it at the start of data section sets a max limitation for latter ```.align```? – yyuze Mar 13 '21 at 13:31
  • Uh, `.balign` has to go right *before* the label: data you want aligned, not after. After any *other* data that precedes it, of course. Like I keep saying, it pads to make the current position (after the .align / .balign directive) aligned. That is all. Everything else follows from understanding that. (And the more basic concept that assemblers work by emitting bytes into the current section, in order, according to each source line.) There is little to no magic here; assembly is all about building things out of very simple rules / building blocks. – Peter Cordes Mar 13 '21 at 13:33
  • 1
    @PeterCordes Ok! I got it! The core idea is that the assembler replaces ```.align ${alignment}``` with zero bytes to approach the closest boundary which satisfies ***address % ${alignment} == 0***. – yyuze Mar 13 '21 at 13:42
  • Yup, exactly. That's why I linked https://sourceware.org/binutils/docs/as/Balign.html earlier :P – Peter Cordes Mar 13 '21 at 13:46
  • : ) Thank you for your great patience! – yyuze Mar 13 '21 at 13:48

0 Answers0