在gcc的堆栈初始化中,是否可以避免从另一个部分复制?

在gcc的堆栈初始化中,是否可以避免从另一个部分复制?,c,gcc,x86,C,Gcc,X86,比如说 void f() { wchar_t s[]=L"aaaaaaaaa"; } 被编译成类似 .section .rdata LC0:.ascii "a\0a\0a\0a\0a\0a\0\0" .section .text movl LC0,%eax movl %eax,0x888(%esp) ... 是否有可能避免对另一部分的依赖?比如 movl$0x00610061,0x888(%esp);movl$0x00610061,0x88c(%esp)您忘了启用优化,因此可能会出现糟

比如说

void f()
{
   wchar_t s[]=L"aaaaaaaaa";
}
被编译成类似

.section .rdata
LC0:.ascii "a\0a\0a\0a\0a\0a\0\0"
.section .text
movl LC0,%eax
movl %eax,0x888(%esp)
...
是否有可能避免对另一部分的依赖?比如


movl$0x00610061,0x888(%esp);movl$0x00610061,0x88c(%esp)

您忘了启用优化,因此可能会出现糟糕的代码

gcc-O3-m32
使用mov immediate进行此操作。

(当然,使用
volatile
这样数组就不会优化。或者将指向它的指针传递给非内联函数)

64位代码以16字节块的形式复制。(不幸的是,即使SSE3或AVX可用,也不使用广播负载)

这显然是值得的,尽管使用64位立即数和4个qword存储+1个dword的movabs并不可怕

# gcc9.3 -O3 -march=skylake
# with the default tuning / arch options, same code but without "v"
f():
        vmovdqa xmm0, XMMWORD PTR .LC0[rip]      # should have used vpbroadcastd
        vmovaps XMMWORD PTR [rsp-56], xmm0         # it chooses two 16-byte stores
        vmovaps XMMWORD PTR [rsp-40], xmm0         # maybe to avoid a vzeroupper or alignment isn't known
        mov     QWORD PTR [rsp-24], 97           # scalar mov-immediate for the last one
        ret
.LC0:
        .quad   416611827809
        .quad   416611827809

似乎OP的
wchar\u t
是2个字节,这将使代码更类似于(但是的,基本上是相同的故事)。@MarcoBonelli:哦,对了,在Windows上
wchar\u t
是2个字节。但是,是的,同样的故事,幸运的是答案并不取决于这个事实。
# gcc9.3 -O3 -march=skylake
# with the default tuning / arch options, same code but without "v"
f():
        vmovdqa xmm0, XMMWORD PTR .LC0[rip]      # should have used vpbroadcastd
        vmovaps XMMWORD PTR [rsp-56], xmm0         # it chooses two 16-byte stores
        vmovaps XMMWORD PTR [rsp-40], xmm0         # maybe to avoid a vzeroupper or alignment isn't known
        mov     QWORD PTR [rsp-24], 97           # scalar mov-immediate for the last one
        ret
.LC0:
        .quad   416611827809
        .quad   416611827809