Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my const array stored on the stack instead of the text section?

I'm implementing a encryption algorithm (for educational purposes) and I noticed something strange. Part of the algorithm uses s-boxes to do substitution, so I allocated const arrays to use as a lookup table like this:

const unsigned char s0_lookup[4][4]={{1,0,3,2},
                                     {3,2,1,0},
                                     {0,2,1,3},
                                     {3,1,3,2}};
const unsigned char s1_lookup[4][4]={{0,1,2,3},
                                     {2,0,1,3},
                                     {3,0,1,0},
                                     {2,1,0,3}};

Since the arrays use the const qualifier I thought they should be stored in the text area rather than on the stack. However, if I dissassemble the output of the compiler I see this:

0000000000000893 <s_des_sbox>:
893:   55                      push   %rbp
894:   48 89 e5                mov    %rsp,%rbp
897:   48 89 7d c8             mov    %rdi,-0x38(%rbp)
89b:   c6 45 dd 00             movb   $0x0,-0x23(%rbp)
89f:   c6 45 e0 01             movb   $0x1,-0x20(%rbp)
8a3:   c6 45 e1 00             movb   $0x0,-0x1f(%rbp)
8a7:   c6 45 e2 03             movb   $0x3,-0x1e(%rbp)
8ab:   c6 45 e3 02             movb   $0x2,-0x1d(%rbp)
8af:   c6 45 e4 03             movb   $0x3,-0x1c(%rbp)
8b3:   c6 45 e5 02             movb   $0x2,-0x1b(%rbp)
8b7:   c6 45 e6 01             movb   $0x1,-0x1a(%rbp)
8bb:   c6 45 e7 00             movb   $0x0,-0x19(%rbp)
8bf:   c6 45 e8 00             movb   $0x0,-0x18(%rbp)
8c3:   c6 45 e9 02             movb   $0x2,-0x17(%rbp)
8c7:   c6 45 ea 01             movb   $0x1,-0x16(%rbp)
8cb:   c6 45 eb 03             movb   $0x3,-0x15(%rbp)
8cf:   c6 45 ec 03             movb   $0x3,-0x14(%rbp)
8d3:   c6 45 ed 01             movb   $0x1,-0x13(%rbp)
8d7:   c6 45 ee 03             movb   $0x3,-0x12(%rbp)
8db:   c6 45 ef 02             movb   $0x2,-0x11(%rbp)
8df:   c6 45 f0 00             movb   $0x0,-0x10(%rbp)
8e3:   c6 45 f1 01             movb   $0x1,-0xf(%rbp)
8e7:   c6 45 f2 02             movb   $0x2,-0xe(%rbp)
8eb:   c6 45 f3 03             movb   $0x3,-0xd(%rbp)
8ef:   c6 45 f4 02             movb   $0x2,-0xc(%rbp)
8f3:   c6 45 f5 00             movb   $0x0,-0xb(%rbp)
8f7:   c6 45 f6 01             movb   $0x1,-0xa(%rbp)
8fb:   c6 45 f7 03             movb   $0x3,-0x9(%rbp)
8ff:   c6 45 f8 03             movb   $0x3,-0x8(%rbp)
903:   c6 45 f9 00             movb   $0x0,-0x7(%rbp)
907:   c6 45 fa 01             movb   $0x1,-0x6(%rbp)
90b:   c6 45 fb 00             movb   $0x0,-0x5(%rbp)
90f:   c6 45 fc 02             movb   $0x2,-0x4(%rbp)
913:   c6 45 fd 01             movb   $0x1,-0x3(%rbp)
917:   c6 45 fe 00             movb   $0x0,-0x2(%rbp)
91b:   c6 45 ff 03             movb   $0x3,-0x1(%rbp)

The code is moving literal constants to populate an empty array on the stack! This seems horribly inefficient to me, when the whole array could simply be stored as a constant. Why is my code doing this?

like image 294
Robert Stiffler Avatar asked Feb 25 '16 10:02

Robert Stiffler


People also ask

Are arrays stored on the stack?

Yes, the whole array is pushed on stack.

Is array stored in stack or heap?

In Java reference types are stored in the Heap area. As arrays are also reference types, (they can be created using the “new” keyword) they are also stored in the Heap area.

Where are static arrays stored in C?

The static variables are stored in the data segment of the memory. The data segment is a part of the virtual address space of a program. All the static variables that do not have an explicit initialization or are initialized to zero are stored in the uninitialized data segment( also known as the BSS segment).

Where are arrays stored in C++?

It is stored in what's called row-order, meaning by row. In memory, the second row follows the first row, and the third row follows the second row. If you want to be able to alter the size of your array at run time, then declare dynamic arrays. These are done with pointers and the new operator.


1 Answers

As it is declared in a function and non static, it is normally allocated on the stack. As C allows recursion, every new call of your function will get a new fresh copy of the array, populated at run-time.

To make it initialized only once at build time, you should make it static:

static const unsigned char s0_lookup[4][4]={{1,0,3,2},
                                     {3,2,1,0},
                                     {0,2,1,3},
                                     {3,1,3,2}};

As it is declared const, optimization could make use of the as-if rule and compile it as you had written static const ... but nothing forces the compiler to do it.

like image 70
Serge Ballesta Avatar answered Nov 18 '22 19:11

Serge Ballesta