How can I unsubscribe from this group? TIA -----Original Message----- From: gcc-help-owner@xxxxxxxxxxx [mailto:gcc-help-owner@xxxxxxxxxxx] On Behalf Of sztfg@xxxxxxxxx Sent: Monday, February 11, 2013 5:02 AM To: Ian Lance Taylor Cc: gcc-help@xxxxxxxxxxx Subject: Re: Ways to fill the stack 10.02.2013, 21:44, "Ian Lance Taylor" <iant@xxxxxxxxxx>: > On Sat, Feb 9, 2013 at 10:42 PM, <sztfg@xxxxxxxxx> wrote: > >> 10.02.2013, 10:13, "Ian Lance Taylor" <iant@xxxxxxxxxx>: >>> I don't see why this would ever use a push instruction. Arguments >>> are >>> passed in registers on x86_64. For each call the local array is >>> built >>> on the stack, then the address of the array is passed in a register. >> Local array can be build on the stack, using push instruction. > > Sure, but why would that be a good idea? > > In any case GCC does not generally use push instructions for local > variables. Instead GCC allocates a frame on the stack, and fills in > values as needed. GCC does in some cases use push instructions to > push arguments to functions. Is there any reason that GCC should use > push instructions for local variables? > > Ian For this case: #define setarr(a) [sizeof(a)-1] = (a) // remove NULL from end of string void foo(void) { const char a2 setarr( "0000""0000" "0001""0001" "0002""0002" "0003""0003" "0004""0004" "0005""0005"); bar(a2); return; } with gcc -c -march=native -O2 sample.c -o sample.o I got this: Disassembly of section .text: 0000000000000000 <foo>: 0: 48 83 ec 38 sub $0x38,%rsp 4: 49 b8 30 30 30 30 30 movabs $0x3030303030303030,%r8 b: 30 30 30 e: 48 bf 30 30 30 31 30 movabs $0x3130303031303030,%rdi 15: 30 30 31 18: 4c 89 04 24 mov %r8,(%rsp) 1c: 48 89 7c 24 08 mov %rdi,0x8(%rsp) 21: 48 be 30 30 30 32 30 movabs $0x3230303032303030,%rsi 28: 30 30 32 2b: 48 b9 30 30 30 33 30 movabs $0x3330303033303030,%rcx 32: 30 30 33 35: 48 89 74 24 10 mov %rsi,0x10(%rsp) 3a: 48 89 4c 24 18 mov %rcx,0x18(%rsp) 3f: 48 ba 30 30 30 34 30 movabs $0x3430303034303030,%rdx 46: 30 30 34 49: 48 b8 30 30 30 35 30 movabs $0x3530303035303030,%rax 50: 30 30 35 53: 48 89 54 24 20 mov %rdx,0x20(%rsp) 58: 48 89 44 24 28 mov %rax,0x28(%rsp) 5d: 48 89 e7 mov %rsp,%rdi 60: 31 c0 xor %eax,%eax 62: e8 00 00 00 00 callq 67 <foo+0x67> 67: 48 83 c4 38 add $0x38,%rsp 6b: c3 retq As you can see, mov %r8,(%rsp) produse 4 bytes: 4c 89 04 24 and mov %rdi,0x8(%rsp) produces 5 bytes: 48 89 7c 24 08 push %r8 produces only 2 byte 41 50 and push %rax (or %rcx %rdx ...) produces one byte You can check other instruction length, for example movq %rax, (%rsp) etc. If we need to load bigger chunk to the stack: #define setarr(a) [sizeof(a)-1] = (a) // remove NULL from end of string void foo(void) { const char a2 setarr( "0000""0000" "0001""0001" "0002""0002" ... "0017""0017" "0018""0018" "0019""0019"); bar(a2); return; } it produce this: ... .LC0: .string "0000000000010001000200... ... movl $.LC0, %esi movq %rsp, %rdi movl $20, %ecx xorl %eax, %eax rep movsq movq %rsp, %rdi call bar ... This can be replaced (for very large data) to something like http://build.shr-project.org/sources/svn/www.eglibc.org/svn/branches/eglibc-2_14/libc/sysdeps/x86_64/multiarch/memcpy-ssse3.S Unfortunately, x86-64 can't push xmm