1

I'm a beginner in assembly, so the answer to my question probably is totaly obvious for most of you, but not for me. Please don't blame.

On a 64-bit-system this C-code:

 1| int main ()
 2| {
 3| char ary[230];
 4| ary[0] = 2;
 5| return 0;
 6| }

results in this assembly code:

 7| push rbp
 8| mov rbp, rsp
 9| sub rsp, 120
10| mov BYTE PTR [rbp-240], 2
11| mov eax, 0
12| leave
13| ret

I would expect that the stackpointer reserves at least 230 byte (probably a bit more), so that 'ary' (line 3) can be stored in it. But in line 9 the stackpointer is only decremented by 120 byte. This results in a buffer of 120 byte between the basepointer rbp and [rbp-120]. That's too small for 'ary' (230 byte). And as can bee seen in line 10, ary-index '0' is stored at [rbp-240], which is 240 byte below the basepointer, so 120 byte below the buffer, which ends (more precisely begins) at [rbp-120]. So it seems as if a part of 'ary' is stored outside the buffer.

Of course not the compiler is confused, but I am. So my question is: What do I misunderstand here? Maybe in line 9 it's not 120 byte, but 120 * WORD (120 * 2 bytes = 240 byte, what would fit)? That would mean that we have mixture of a byte-number (line 10) and a WORD-number (line 9) here. Then my question would be, how can I see in assembly, if a number is a byte-number, WORD-number, DWORD-number...? Sure, in line 10 it's specified as 'BYTE', but what about line 9?

Thank you for answering!

fuz
  • 88,405
  • 25
  • 200
  • 352
a kind person
  • 329
  • 1
  • 6
  • 17
  • 2
    You are on a system using the sysv abi which allows for a 128 byte red zone, that is a region of stack that can be used under the stack pointer. 120 bytes allocated + 128 bytes red zone = 248 bytes > 230 bytes required. – Jester Feb 03 '19 at 15:15
  • @Jester Thank you! – a kind person Feb 03 '19 at 15:44
  • 1
    See https://stackoverflow.com/tags/red-zone/info for more. And BTW, in asm numbers in registers are always just integers, you were understanding it correctly. *Pointers are just integers with values that are valid addresses*. There's never any magic scaling by type width, you always have to do that yourself (with a scaled-index addressing mode, or by writing `sub rsp, 120 * 2` or w/e.) – Peter Cordes Feb 03 '19 at 23:11
  • @Peter Thank you for clarifying! I'm wondering, why stackoverflow didn't show me the already asked question when I searched for it... – a kind person Feb 04 '19 at 15:59
  • IDK; SO's built-in search isn't always very good. But I think I found it by looking through recent `[red-zone]` questions, instead of using google with `site:stackoverflow.com` like I usually do. Maybe you used a search term that didn't appear in the duplicate question, so it got filtered out. – Peter Cordes Feb 04 '19 at 22:27

0 Answers0