I was recently reading reverse engineering for beginners by Yurichev where I happened to come across an example x64 MSVC and x64 GCC code. In this I'm unable to understand why there is a shadow space of 16 bytes present in both MSVC and GCC.
Firstly, MSVC does SUB RSP, 56 out of which only 8 bytes (64-bit) of space will be used for any data type equal to or shorter than 8 bytes as mentioned here- Hence, since there is only one variable, 8 bytes are sufficient for storing its value, but the compiler adds additional 48 bytes of space. Assuming that this space is used to build the next call, we can say 32 bytes are shadow space for the first 4 arguments in Win64, and even then we will have 16 bytes of extra space. Furthermore, the variable is located in RSP+32 which is equal to RBP-24 rather than RBP - 8. I'm not sure I understand the reason why for all of these issues.
This leads to the next example code. The situation is the same and it was mentioned earlier in the book that using 8 bytes aligned values for x64 and 4 bytes aligned values for x86 increases performance. And going by that primer, every x64 variable should be located on a 8 byte boundary for performance reasons. In this case, the optimizing GCC is using RSP + 12 (not a multiple of 8) to store the local variable which turns out to be RBP - 12 instead of storing it at RBP - 8 or RBP - 16 which makes no sense to me at all.
Hence I want clarification regarding 5 points- 1. Why is there such a large shadow space in x64 MSVC? 2. Why is the value present at RSP+32 instead of RBP-8 in the MSVC example? 3. Why is the value present at RSP+12 instead of RBP-8 in the Optimizing GCC example? 4. Why is thr GCC value present on an offset not divisible by 8? 5. Are all data types shorter than 8 bytes rounded off to 8 bytes in x64 and all data types shorter than 4 bytes rounded off to 4 bytes in x86 environments respectively as mentioned?