2

there is something that is don't understand in this code

using System;

namespace hello
{
    public class Program
    {
        public static void Main(string[] args)
        {
            
            string a = "hi";
            Console.WriteLine(a);
            a = "bye";
            Console.WriteLine(a);
        }
        
    }
}

this code looks in JIT asm like this

hello.Program..ctor()

L0000: ret

hello.Program.Main(System.String[])

L0000: sub rsp, 0x28
L0004: mov rcx, 0x28cfff6fd60
L000e: mov rcx, [rcx]
L0011: call System.Console.WriteLine(System.String)
L0016: mov rcx, 0x28cfff6fd58
L0020: mov rcx, [rcx]
L0023: add rsp, 0x28
L0027: jmp System.Console.WriteLine(System.String)

Why is there sub/add rsp, 0x28 in L0000 and L0023?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847

1 Answers1

-3

sub rsp, 0x28

This means substract 0x28 (40 decimal) from the stack pointer register (r = register, sp = stack pointer).

You need this because you have a stack base variable (string a). 40 bytes seems like quite a few bytes, but there will be some other housekeeping required.

The add rsp,28 at the end of the function is the 'tidying up` that is required before returning from the function (basically putting the stack pointer back to where it was at the start of the function). Why is it BEFORE the final call? I guess the compiler knew that there were no other side effects of reordering the instructions, and it's probably 'more efficient' to do it in this order.

Neil
  • 11,059
  • 3
  • 31
  • 56
  • 1
    *You need this because you have a stack base variable (string a)* - no, the asm isn't storing any local vars to the stack, or generating any pointers to the stack. Notice that it's using `mov rcx, 0x28cfff6fd60` with what looks like the absolute address of a string object or something. – Peter Cordes Apr 09 '21 at 20:53
  • 3
    40 bytes is 32-byte shadows space plus another 8 to keep RSP 16-byte aligned before a `call`. The reason it can clean up the stack before the final call is that it's *not* a `call` + `ret`, it's `jmp` optimized tailcall that jumps to the next function with the stack set up exactly as it was on entry to this function (including pointing at our own return address). – Peter Cordes Apr 09 '21 at 20:54
  • typo: "shadow space" not "shadows space", sorry. – Peter Cordes Apr 10 '21 at 01:27
  • I have no idea about this stuff they are too complicated for my level, @PeterCordes but thanks for correcting him and me :) – Crazy Simon Apr 10 '21 at 21:24