<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx</link><description>A Summary of the x64 calling conventions with links to the official document - a handy reference for folks just starting to port a compiler, or needing to author some assembly code.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#652789</link><pubDate>Sat, 01 Jul 2006 01:02:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:652789</guid><dc:creator>anonymous coward</dc:creator><description>Please add these links to your blog:&lt;br&gt;&lt;br&gt;&lt;a rel="nofollow" target="_new" href="http://msdn.microsoft.com/library/en-us/debug/base/structured_exception_handling_functions.asp"&gt;http://msdn.microsoft.com/library/en-us/debug/base/structured_exception_handling_functions.asp&lt;/a&gt; &lt;br&gt;&lt;br&gt;&lt;a rel="nofollow" target="_new" href="http://msdn2.microsoft.com/en-us/library/7kcdt6fy.aspx"&gt;http://msdn2.microsoft.com/en-us/library/7kcdt6fy.aspx&lt;/a&gt;&lt;br&gt;&lt;br&gt;This because my fellow workers started using your blog as ultimate source of reality and imho this is dumb.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=652789" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#572894</link><pubDate>Tue, 11 Apr 2006 02:56:04 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:572894</guid><dc:creator>Slava</dc:creator><description>OK, it seems that _local_unwind just calls RtlUnwindEx with appropriate parameters.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=572894" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#571209</link><pubDate>Sat, 08 Apr 2006 01:48:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:571209</guid><dc:creator>Slava</dc:creator><description>Hi Kevin,&lt;br&gt;&lt;br&gt;Could you tell anything about _local_unwind routine? From some sources I know that it should be called every time the flow of control leaves guarded block of __try/__finally construct. It takes two arguments and it calls termination handler by itself.&lt;br&gt;&lt;br&gt;But I found nothing about this routine in Microsoft documentation! It makes me feel bad :(&lt;br&gt;&lt;br&gt;Please, give me any hints about it.&lt;br&gt;Thanks!&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=571209" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#553409</link><pubDate>Fri, 17 Mar 2006 05:34:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:553409</guid><dc:creator>asdf</dc:creator><description>I forgot that my all time favorite example of this is:&lt;br&gt;&lt;br&gt;HRESULT IDirect3DDevice9::SetRenderState(&lt;br&gt;D3DRENDERSTATETYPE State,&lt;br&gt;DWORD Value&lt;br&gt;);&lt;br&gt;&lt;br&gt;Because the D3D programmers were too lazy to add another function that took a float, here is what their documentation says for a few render states:&lt;br&gt;&lt;br&gt;&amp;quot;Values for the this render state are floating-point values. Because the IDirect3DDevice9::SetRenderState method accepts DWORD values, your application must cast a variable that contains the value, as shown in the following code example.&lt;br&gt;&lt;br&gt;pDevice9-&amp;gt;SetRenderState(D3DRS_FOGSTART, *((DWORD*) (&amp;amp;fFogStart)));&amp;quot;&lt;br&gt;&lt;br&gt;Which assumes sizeof(DWORD) == sizeof(float) and alignof(dword) % alignof(float) == 0. But most importantly this is undefined due to aliasing. The only correct way is to use a memcpy (or equivalent).&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=553409" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#553404</link><pubDate>Fri, 17 Mar 2006 05:23:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:553404</guid><dc:creator>asdf</dc:creator><description>- Why does *ABI* documentation mention malloc? That's a C runtime library function and has nothing to do with ABI.&lt;br&gt;&lt;br&gt;- Why does it say &amp;quot;recommended alignment&amp;quot;. It should just list the minimum alignment.&lt;br&gt;&lt;br&gt;- The ABI documentation doesn't mention that function pointers may be allowed to be cast to data pointers. This is a divergence from the C standard.&lt;br&gt;&lt;br&gt;- This ABI documentation says nothing about aliasing. The winapi is notoriously bad for getting const and aliasing wrong as far as the C standard is concerned. The two most common examples of broken aliasing in the winapi are:&lt;br&gt;&lt;br&gt;int and long are the same representation on Windows so Microsoft programmers use these interchangably. The problem is that they are not interchangable as far as the C standard is concerned. Depending on which header files or versions of header files a module gets compiled with:&lt;br&gt;&lt;br&gt;void foo(int *);&lt;br&gt;&lt;br&gt;in one translation unit becomes&lt;br&gt;&lt;br&gt;void foo(long *);&lt;br&gt;&lt;br&gt;in another. This has huge reprocussions as far as the C standard is concerned and it also breaks the ODR of C++. A somewhat related annoyance was this one winapi header file that would do this (I don't know if this was the exact types, but it was similar):&lt;br&gt;&lt;br&gt;typedef int ptrdiff_t;&lt;br&gt;typedef unsigned int size_t;&lt;br&gt;&lt;br&gt;But on my compiler it was actually:&lt;br&gt;&lt;br&gt;typedef long ptrdiff_t;&lt;br&gt;typedef unsigned long size_t;&lt;br&gt;&lt;br&gt;And this would break my overloads and name mangling depending on the order of header files included. For example:&lt;br&gt;&lt;br&gt;struct foo {&lt;br&gt;	char &amp;amp; operator[](ptrdiff_t);&lt;br&gt;	operator char *();&lt;br&gt;};&lt;br&gt;&lt;br&gt;the *exact* type of ptrdiff_t is essential for the C++ compiler to resolve:&lt;br&gt;&lt;br&gt;foo f;&lt;br&gt;f[0];&lt;br&gt;&lt;br&gt;into the intended call.&lt;br&gt;&lt;br&gt;&lt;br&gt;The other common occurance is the void ** in the COM IUnknown::QueryInterface function. The dummy who designed it used void ** as (incorrectly) &amp;quot;generic pointer to pointer&amp;quot; instead of (correctly) &amp;quot;pointer to generic pointer&amp;quot; which breaks aliasing depending on what the correct code is. Unfortunately, I can't tell what the correct code is as I have seen a ton of different examples in the wild but I am convinced that the following is the *only* correct way because it's the only one guaranteed to work by the C++ standard no matter what weird machines it runs on:&lt;br&gt;&lt;br&gt;HRESULT Foo::QueryInterface(quid_t g, void **ptr)&lt;br&gt;{&lt;br&gt;	*ptr = 0;&lt;br&gt;	if (q == BLAH_GUID)&lt;br&gt;		ptr = static_cast&amp;lt;IBlah*&amp;gt;(this);&lt;br&gt;	...&lt;br&gt;}&lt;br&gt;&lt;br&gt;IBlah *blah;&lt;br&gt;void *ptr;&lt;br&gt;p-&amp;gt;QueryInterface(BLAH_GUID, &amp;amp;ptr);&lt;br&gt;blah = static_cast&amp;lt;IBlah*&amp;gt;(ptr);&lt;br&gt;// or equivalently&lt;br&gt;blah = (void*)ptr;&lt;br&gt;&lt;br&gt;Every other example is incorrect, including:&lt;br&gt;&lt;br&gt;p-&amp;gt;QueryInterface(blah_guid, (void**)&amp;amp;blah);&lt;br&gt;&lt;br&gt;// or&lt;br&gt;&lt;br&gt;p-&amp;gt;QueryInterface(blah_guid, &amp;amp;ptr);&lt;br&gt;blah = reinterpret_cast&amp;lt;IBlah*&amp;gt;(ptr);&lt;br&gt;&lt;br&gt;// or&lt;br&gt;&lt;br&gt;HRESULT Foo::QueryInterface(quid_t g, void **ptr)&lt;br&gt;{&lt;br&gt;	ptr = reinterpret_cast&amp;lt;IBlah*&amp;gt;(this);&lt;br&gt;&lt;br&gt;// or&lt;br&gt;&lt;br&gt;	ptr = reinterpret_cast&amp;lt;void*&amp;gt;(static_cast&amp;lt;IBlah*&amp;gt;(this));&lt;br&gt;&lt;br&gt;// or&lt;br&gt;	*reinterpret_cast&amp;lt;IBlah**&amp;gt;(ptr) = this;&lt;br&gt;&lt;br&gt;// etc.&lt;br&gt;&lt;br&gt;}&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=553404" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#545486</link><pubDate>Tue, 07 Mar 2006 21:46:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:545486</guid><dc:creator>Kevin Frei</dc:creator><description>BTW - there's no inline assembly because, well, it's a lot of work, and we didn't have a lot of time to do it in (at least it didn't seem that way at first). &amp;nbsp;Inline assembly also tends to get in the way of the optimizer, and it also tends to let people write code that works most of the time, until they realize that they didn't understand the ABI, and now the code they deployed to customers can't properly handle exceptions, nor can they debug the crash dumps... &amp;nbsp;We'll probably be adding inline asm support in the future (not the next product release, though). &amp;nbsp;In the mean time, there is a pretty complete list of intrinsic functions in intrin.h...&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=545486" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#545448</link><pubDate>Tue, 07 Mar 2006 21:04:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:545448</guid><dc:creator>Kevin Frei</dc:creator><description>That means that all functions must starts with a 2 byte instruction, and must be preceded by 6 bytes of padding. &amp;nbsp;I'll write a new post about that in the next few days...&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=545448" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#545018</link><pubDate>Tue, 07 Mar 2006 07:00:17 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:545018</guid><dc:creator>manhattan</dc:creator><description>Do you know what &amp;quot;hot-patchability&amp;quot; means ?&lt;br&gt;&lt;br&gt;Quote:&lt;br&gt;&lt;br&gt;&amp;quot;All x64 functions are required to be hot-patchable, in order to enable both high availability, and maximum security.&amp;quot;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=545018" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#535079</link><pubDate>Sun, 19 Feb 2006 20:35:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:535079</guid><dc:creator>Billy Rose</dc:creator><description>How about some examples with extensive embedded comments for each line of code that handles all of the situations, i.e.: this is a leaf function with all of the data structures required, this is a non-leaf function with all data structures required, this is an exception handler with all required data structures, etc.&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=535079" width="1" height="1"&gt;</description></item><item><title>re: x64 ABI vs. x86 ABI (aka Calling Conventions for AMD64 &amp; EM64T)</title><link>http://blogs.msdn.com/b/freik/archive/2006/03/06/x64-calling-conventions-summary.aspx#449238</link><pubDate>Tue, 09 Aug 2005 03:11:41 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:449238</guid><dc:creator>Bruce Frost</dc:creator><description>Very good so far.  My problem is that the detailed information leaves out some of the most important details.  I am well aware of how structured exception handling works internally in x86 32-bit but no idea what happens in 64-bit.&lt;br&gt;&lt;br&gt;The official document is missing a description of where the unwind information is located and how to find the unwind information for a function at some location.&lt;br&gt;&lt;br&gt;Also, it would help to describe how exception handling in X64 works in the same detail of the article by Matt Pietrek at:&lt;br&gt; &lt;a rel="nofollow" target="_new" href="http://www.microsoft.com/msj/0197/exception/exception.aspx"&gt;http://www.microsoft.com/msj/0197/exception/exception.aspx&lt;/a&gt;&lt;br&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=449238" width="1" height="1"&gt;</description></item></channel></rss>