2016-08-22 40 views
2

The "this" pointer「這個」指針CLR ABI文檔中

AMD64只:最多的.NET Framework 4.5中,管理「這個」指針被 一樣處理原生「這個」指針(這意味着它是當呼叫使用返回緩衝區並且在RDX 而不是RCX中通過時的第二個 參數。

我找到了CLR ABI文檔中的上述說法,根據我的理解,它是由.NET框架4.5,「this」指針是在呼叫使用的回報緩衝,是第二個參數通過了RDX;

所以我有兩個問題:

  1. 什麼是用於緩衝的含義是什麼?指向流緩衝區的緩衝區如httpwebresponse或其他什麼?

  2. 如果我們使用靜態類,我認爲在這種情況下,沒有「this」指針存在並且上述語句指定給實例對象,對吧?

+0

有關x64調用約定的MSDN文檔中的[返回值](https://msdn.microsoft.com/zh-cn/library/7572ztz4.aspx)中描述了返回緩衝區:*否則,調用者將採用分配內存和傳遞返回值的指針作爲第一個參數的責任。* –

回答

8

很明顯,微軟一直在修補他們的x64 abi。確切地說,他們做了什麼,什麼時候什麼時候,甚至是什麼時候都很不清楚,文件是不完整的,分散的,並且過時的。我個人認爲Agner Fog所做的reverse-engineering work只是真正可靠的信息來源。但是他沒有處理託管代碼生成。

這個在4.5中被改變的說法是不合情理的。更有可能的是,RyuJIT改變了這種情況,RyuJIT是新的x64抖動,用於替換運行緩慢且無法維護的傳統x64抖動。最初在4.5.3版本的預覽版中發佈,可能是對4.5版的說明進行解釋,但是會在4.6後增加。這種改變的一個可能的靈感是.NETCore項目,Microsoft x64 abi與Unix代碼生成器(GNU和LLVM)的區別是相當痛苦的。

但與C++編譯器代碼生成器的更改(根據Agner Fog,gack在VS2015更新中修改)不同,此更改不太可能中斷。不匹配只能發生在pinvoke中,抖動從來不支持CallingConvention.ThisCall。幸運的是,您的問題很容易回答:

緩衝區的含義是什麼?

這隻對返回「聚集類型」的方法有用。換句話說,一個不再適合CPU寄存器的值。在C#中,這是一個struct,並進一步規定它必須是非平凡的(超過2個成員或非平凡的字段類型)。

方法調用方必須爲其返回值(「緩衝區」)在其堆棧幀中分配空間並將指針傳遞到該空間。該指針作爲該方法隱藏的額外參數傳遞。傳統上第一個參數,在隱藏this參數之前。這使this成爲第二個參數,因此通過RDX寄存器而不是RCX寄存器。該更改反轉訂單,this始終是第一個參數並通過RCX傳遞,返回值指針是第二個。被調用的方法在返回之前將返回值複製到該緩衝區中。

怎麼樣,如果我們使用靜態類

只有相關的靜態方法。然後沒有額外的隱藏this參數,所以它被省略。實際上,從以前的方式來看,沒有任何變化,隱藏的返回值指針自動總是第一個參數,並因此通過RCX傳遞。

如果這對你很重要,那麼一定要利用調試器的調試> Windows>反彙編窗口。在一個小測試程序上運行它,它很容易告訴你使用哪個寄存器。