2

While reading the book Computer Systems A Programmers Approach I came across the following section, where the book shows some assembly code and the states of the %rsp register while storing addresses to pass control(It starts at the bottom):

<leaf>:
lea    0x2(%rdi), %rax.          //%rsp at 0x7fffffffe810  storing 0x4004e
retq

<top>:
sub    $0x5,%rdi.                //%rsp at 0x7fffffffe818 storing 0x400560
callq  400540 <leaf>.            
add    %rax,%rax
retq

<main>:
callq  400545 <top>              //%rsp at 0x7fffffffe820
mov    %rax,%rax

Where the stored addresses are for the next instruction after each call.

I fail to see the logic behind the bytes allocated to %rsp here, it makes sense to allocate 3 bytes since that's enough to represent the addresses, but it allocates 2 bytes on the first call and then 8 bytes on the next one. Does %rsp point to an unused space and that's why it can just decrement 2 bytes? Then why does it decrement 8 on the call to leaf?

1 Answers1

4

but it allocates 2 bytes on the first call and then 8 bytes on the next one

It always allocates 8 bytes. It does not depend on the small value of the address 0x400560.
The numbers in the comments are in hexadecimal (because of the 0x prefix)!

  0x7fffffffe820
- 0x7fffffffe818
  --------------
               8

  0x7fffffffe818
- 0x7fffffffe810
  --------------
               8
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 2
    Thanks, I feel kinda ashamed because I realized they were hex but somehow my brain defaulted to decimal arithmetic and I lost a couple hours trying to find the answer. – GabrielBRAA Jan 13 '23 at 21:08
  • Most calling conventions require the code to maintain "stack alignment" which means that the same number of bytes, most often a power of 2, will be subtracted to allocate memory, regardless of the actual size of the data. Even if the value doesn't need all 8 bytes to be represented, eight bytes are still reserved. Until I understood this concept I was very confused why many programming examples would declare a variable representing a person's age as an `int` even though people don't live past 255. I thought they were needlessly wasting memory. – puppydrum64 Feb 02 '23 at 11:20