首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在CIL中的函数调用中传递参数?

问如何在CIL中的函数调用中传递参数?
EN

Stack Overflow用户
提问于 2011-03-21 22:24:21
回答 2查看 2.1K关注 0票数 3

我正在尝试学习CIL代码,但无法理解一个函数的返回值是如何作为参数传递给另一个函数的。

我已经为以下函数生成了CIL代码:

代码语言:javascript
复制
  public bool TestWebPage()
  {
    WebRequest request = WebRequest.Create("http://www.costco.com");
    request.Proxy.Credentials = CredentialCache.DefaultCredentials;
  }

CIL代码:

代码语言:javascript
复制
//000021:     public void TestWebPage()
//000022:     {
    IL_0000:  /* 00   |                  */ nop
   .line 23,23 : 7,71 ''
//000023:       WebRequest request = WebRequest.Create("http://www.costco.com");
IL_0001:  /* 72   | (70)000001       */ ldstr      "http://www.costco.com" /* 70000001  */
  IL_0006:  /* 28   | (0A)000012       */ call       class [System/*23000003*/]System.Net.WebRequest/*01000016*/ [System/*23000003*/]System.Net.WebRequest/*01000016*/::Create(string) /* 0A000012 */
  IL_000b:  /* 0A   |                  */ stloc.0
.line 24,24 : 7,70 ''
//000024:       request.Proxy.Credentials = CredentialCache.DefaultCredentials;
IL_000c:  /* 06   |                  */ ldloc.0
IL_000d:  /* 6F   | (0A)000013       */ callvirt   instance class [System/*23000003*/]System.Net.IWebProxy/*01000017*/ [System/*23000003*/]System.Net.WebRequest/*01000016*/::get_Proxy() /* 0A000013 */
IL_0012:  /* 28   | (0A)000014       */ call       class [System/*23000003*/]System.Net.ICredentials/*01000019*/ [System/*23000003*/]System.Net.CredentialCache/*01000018*/::get_DefaultCredentials() /* 0A000014 */
IL_0017:  /* 6F   | (0A)000015       */ callvirt   instance void [System/*23000003*/]System.Net.IWebProxy/*01000017*/::set_Credentials(class [System/*23000003*/]System.Net.ICredentials/*01000019*/) /* 0A000015 */
IL_001c:  /* 00   |                  */ nop
.line 25,25 : 7,73 ''

具体来说,我无法理解CIL代码中的以下内容:

  1. CLR运行时如何知道set_Credentials将传递从get_DefaultCredentials返回的值,因为除了注释部分"/01000019/“之外,似乎没有任何链接?
  2. CLR如何在当前的get_Proxy实例上调用System.Net.WebRequest,即在CIL代码中是否有指向实例号的指针?
EN

回答 2

Stack Overflow用户

发布于 2011-03-21 22:35:36

  1. 打电话对IL_0012的指令将get_DefaultCredentials的返回值推送到堆栈上,下一行的set_Credentials方法作为参数传递给计算堆栈。
  2. 由request方法返回的WebRequest.Create变量作为局部变量存储在索引0 (stloc.0)处,然后由ldloc.0加载,因此在已加载到计算堆栈的局部变量上调用行IL_000d上的get_Proxy方法。
票数 1
EN

Stack Overflow用户

发布于 2011-03-21 22:37:25

都是基于堆栈的。所发生的情况是将调用返回值get_DefaultCredentials的方法的结果推送到计算堆栈中。

没有神奇的链接,值恰好驻留在堆栈的顶部。

只需查看构造函数调用,首先发生的事情是将字符串"http://www.costco.com"推到计算堆栈的顶部。然后调用构造函数。然后,构造函数弹出计算堆栈的值。最后一个推到堆栈顶部的值是最后一个参数。ldstr在堆栈顶部精确地推送一个值。构造函数调用的结果,它现在是顶部,该引用随后弹出并存储在位置0 stloc.0 (一个局部变量)中。

调用实例方法略有不同,在这种情况下,第一个参数总是对象,所以这里看到的第一个调用是ldloc.0。它将WebRequest对象实例推到计算堆栈的顶部。在这里,我们调用get_Proxy方法,它使用ldloc.0放在那里的计算堆栈顶部的值,并返回返回的对象实例。这有效地替换了计算堆栈顶部的值。但是,现在堆栈的顶部不再是ldloc.0放在那里的值了。

没有什么是真正的传递,它只是推和弹出,关闭和在堆栈上。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5384459

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档