Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Console.WriteLine() use ecx register, event though eax and ebx are free? [duplicate]

Tags:

c#

.net

assembly

I'm doing some reaserch on CIL optimizing techniques. I've created this simple code:

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

When I watch this code in disassembly window, I see something like:

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

I understand that it put 10 into ecx, then used 63A96648 as a pointer to WriteLine() function, but I'm not sure why does it use the ecx register.

I always thought that ecx is used mainly for loop counter (well, it's called "counter register" for a reason...) and I'm not sure why is it used for WriteLine() function, even though eax and ebx are free. Even when I write more complicated functions, in the end it is always ecx just before the WriteLine() function.

I've tried to find anything about it on the Internet and even a few books from my university library, but I've found nothing. Is ecx faster or is there any reason at all why it is used?

I'm perfectly aware that I shouldn't really care too much about it (because as long as it works, I'm fine), but it's just been bugging me for a past few days and I hope that someone could tell me why is this register used.

like image 718
Kamil T Avatar asked Mar 26 '16 11:03

Kamil T


1 Answers

It must use the ECX register, the __clrcall calling convention for x86 demands it. First argument (Number in this case) is passed through ECX, second argument if present is passed through EDX, additional ones are passed through the stack.

You also see the Function() method getting inlined, it disappeared completely and the optimizer could collapse it into a single register assignment. It is the kind of optimization that makes properties indistinguishable from fields.

This is specific to x86, if you allow it to run in 64-bit mode (remove the jitter forcing) then up to 4 arguments are passed through registers (rcx, rdx, r8 and r9). Project > Properties > Build tab, Platform target = AnyCPU and Prefer 32-bit unticked. Ought to be the kind of code to focus on when you study optimization techniques. The 64-bit jitter was rewritten for VS2015, project name RyuJIT.

like image 151
Hans Passant Avatar answered Oct 20 '22 18:10

Hans Passant