CIL之——入栈和出栈顺序

或许大家都听说过,栈是先进后出,队列是先进先出,那CIL代码中入栈和出栈是怎么进行的呢?下面让我们一窥究竟吧!
先看一段简单的CIL代码:

.class public Program extends [mscorlib]System.Object
{
    .method public static void Show()
    {
        .entrypoint
        .maxstack 3
        .locals init(
            string info
        )
        ldstr "Name:{0} Age:{1}"
        ldstr "Guo"
        box string
        ldc.i4 12
        box int32
        call string [mscorlib]System.String::Format(string,object,object)
        stloc.0         
        ldloc.0
        call void [mscorlib]System.Console::WriteLine(string)
        call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
        ret
    }
}

上述CIL代码对应的C#代码如下:

public class Program
{
    public static void Show()
    {
        string info = string.Foramt("Name:{0} Age:{1}","Guo",12);
        Console.WriteLine(info);
        Console.ReadKey();
    }
}

下面开始分析入栈和出栈的顺序:

ldstr "Name:{0} Age:{1}"
ldstr "Guo"
box string
ldc.i4 12
box int32

执行完毕后堆栈中的内容从上到下依次是:12、”Guo”、”Name:{0} Age:{1}”,由于最先入栈的值会处于栈底位置,所以堆栈中的内容从上到下如图:
这里写图片描述
call string [mscorlib]System.String::Format(string,object,object)需要三个参数,所以要从堆栈中弹出三个值。此时12处于栈顶位置,所以首先被弹出,那12被弹出之后是放到string.Format()第1个参数的位置上吗?如果第1个弹出的值放到第1个参数的位置,第2个弹出的值放到第2个参数的位置,第3个弹出的值放到第3个参数的位置,那对应的C#代码应该是这样的:

string info = string.Foramt(12,"Guo","Name:{0} Age:{1}");

然而实际上生成的C#代码应该是这样的:

string info = string.Foramt("Name:{0} Age:{1}","Guo",12);

说明第1个弹出的值放到了最后1个参数的位置,第2个弹出的值放到了倒数第2个参数的位置,第3个弹出的值放到了第1个参数的位置。有一个简单的方法来快速判断方法各个参数对应的值是什么,CIL代码中各参数入栈的先后顺序是:”Name:{0} Age:{1}”、”Guo”、12,将堆栈中的值赋值给方法所需的各个参数后从第1个参数开始方法各个参数的值依次是:”Name:{0} Age:{1}”、”Guo”、12,说明第1个入栈的值就是方法第1个参数的值,第2个入栈的值就是方法第2个参数的值,以此类推。
这就是入栈和出栈的顺序,以及方法需要多个参数时,栈顶的值被弹出后该放到第几个参数的位置上,不知道各位看明白了吗?有意见请留言。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

changuncle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值