为什么Console.WriteLine()使用ecx寄存器,虽然eax和ebx是免费的?

时间:2016-03-26 11:30:30

标签: c# .net assembly

我正在对CIL优化技术进行一些研究。我创建了这个简单的代码:

int Function() { return 10; }
// (...)
int Number = Function();
Console.WriteLine(Number);

当我在反汇编窗口中看到这段代码时,我看到类似的东西:

00252DB0  mov ecx,0Ah  
00252DB5  call 63A96648  
00252DBA  ret  

我知道它将10放入ecx,然后使用63A96648作为指向WriteLine()函数的指针,但我不确定为什么它使用{{1}注册。

我一直认为ecx主要用于循环计数器(好吧,它被称为"计数器寄存器"有一个原因......)我不是确定为什么它用于ecx函数,即使WriteLine()eax是免费的。即使我编写了更复杂的函数,最后它总是在ebx函数之前ecx

我试图在互联网上找到任何关于它的信息,甚至是我大学图书馆的一些书,但我一无所获。是WriteLine()更快还是有任何理由可以使用它?

我完全清楚我不应该太关心它(因为只要它有效,我很好),但它只是在烦我过去几天,我希望有人能告诉我为什么使用这个寄存器。

1 个答案:

答案 0 :(得分:4)

必须使用ECX寄存器,x86的__clrcall调用约定要求它。第一个参数(在这种情况下为数字)通过ECX传递,第二个参数(如果存在)通过EDX传递,其他传递通过堆栈。

您还看到函数()方法被内联,它完全消失,优化器可以将它折叠成单个寄存器赋值。正是这种优化使得属性与字段无法区分。

这特定于x86,如果允许它以64位模式运行(删除抖动强制),则最多4个参数通过寄存器(rcx,rdx,r8和r9)传递。项目>属性>构建选项卡,平台目标= AnyCPU并且首选32位未选中。在研究优化技术时应该关注的代码类型。为VS2015重新编写了64位抖动,项目名称为RyuJIT。