Este código
long long a1[] = {1, 2}, a2[2];
a2[0] = a1[0];
a2[1] = a1[1];
compila para
movdqa .LC0(%rip), %xmm0
leaq -24(%rsp), %rax
movaps %xmm0, -24(%rsp)
e ocorre uma falha de segmentação na última instrução, o que, pelo que entendi, ocorre porque ela -24(%rsp)
não está em um limite de 16 bytes.
Por que isso aconteceria? Existe UB em algum lugar?
Originalmente, eu estava atribuindo matrizes de bytes (com minha própria função memcpy de 3 linhas), este é apenas um exemplo mínimo reproduzível.
Aqui estão todos os detalhes:
-----> /my/working/directory $ cat m.c
static void dontoptimize(void *p) {
asm volatile("" : : "g"(p) : "memory");
}
void _start() {
long long a1[] = {1, 2}, a2[2];
a2[0] = a1[0];
a2[1] = a1[1];
dontoptimize(a2);
while (1) {}
}
-----> /my/working/directory $ gcc --version | head -1
gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
-----> /my/working/directory $ cat r.sh
set -x -e
gcc -nostdlib -static -fno-builtin -O2 -march=x86-64 m.c
objdump -d a.out
gdb -q a.out
-----> /my/working/directory $ sh r.sh
+ gcc -nostdlib -static -fno-builtin -O2 -march=x86-64 m.c
+ objdump -d a.out
a.out: file format elf64-x86-64
Disassembly of section .text:
0000000000401000 <_start>:
401000: f3 0f 1e fa endbr64
401004: 66 0f 6f 05 f4 0f 00 movdqa 0xff4(%rip),%xmm0 # 402000 <_start+0x1000>
40100b: 00
40100c: 48 8d 44 24 e8 lea -0x18(%rsp),%rax
401011: 0f 29 44 24 e8 movaps %xmm0,-0x18(%rsp)
401016: eb fe jmp 401016 <_start+0x16>
+ gdb -q a.out
Reading symbols from a.out...
(No debugging symbols found in a.out)
(gdb) run
Starting program: /my/working/directory/a.out
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401011 in _start ()
(gdb) x/i 0x0000000000401011
=> 0x401011 <_start+17>: movaps %xmm0,-0x18(%rsp)
(gdb) print $rsp
$1 = (void *) 0x7fffffffdf40
(gdb) print (0x7fffffffdf40 - 0x18) % 16
$2 = 8
-march
foi definido x86-64
para mais especificidade, originalmente eu compilei comnative