c++ x86-64 compiler-optimization calling-convention abi

c++ - Optimización de inicialización de matriz



x86-64 compiler-optimization (1)

Al compilar el siguiente fragmento de código (clang x86-64 -O3 )

std::array<int, 5> test() { std::array<int, 5> values {{0, 1, 2, 3, 4}}; return values; }

Produjo el montaje típico que yo esperaría.

test(): # @test() mov rax, rdi mov ecx, dword ptr [rip + .L__const.test().values+16] mov dword ptr [rdi + 16], ecx movups xmm0, xmmword ptr [rip + .L__const.test().values] movups xmmword ptr [rdi], xmm0 ret .L__const.test().values: .long 0 # 0x0 .long 1 # 0x1 .long 2 # 0x2 .long 3 # 0x3 .long 4 # 0x4

Sin embargo, para arreglos pequeños, parece haber descubierto un truco?

std::array<int, 3> test() { std::array<int, 3> values {{0, 1, 2}}; return values; }

This fue la asamblea correspondiente.

test(): # @test() movabs rax, 4294967296 mov edx, 2 ret

¿De dónde vino ese número mágico ( 4294967296 )? ¿Es eso esencialmente un valor que puede reinterpret_cast nuevo en una matriz de int alguna manera?


Un std::array<int, 3> tiene 96 bits de ancho en su implementación. Como tal, ABI declara que debe devolverse en RAX + los 32 bits bajos de RDX (también conocido como EDX).

4294967296 es 2 32 , en hexadecimal es $1''0000''0000 . Así que movabs almacena 0 en los 32 bits de RAX de orden inferior, y 1 en los bits de RAX de orden superior. El mov almacena 2 en EDX (que es exactamente lo que querías).