{"id":3363,"date":"2013-08-30T07:00:00","date_gmt":"2013-08-30T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2013\/08\/30\/can-an-x64-function-repurpose-parameter-home-space-as-general-scratch-space\/"},"modified":"2013-08-30T07:00:00","modified_gmt":"2013-08-30T07:00:00","slug":"can-an-x64-function-repurpose-parameter-home-space-as-general-scratch-space","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20130830-00\/?p=3363","title":{"rendered":"Can an x64 function repurpose parameter home space as general scratch space?"},"content":{"rendered":"<p>\nWe saw some time ago that\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/01\/14\/58579.aspx\">\nthe x64 calling convention in Windows<\/a>\nreserves space for the register parameters on the stack,\nin case the called function wants to spill them.\nBut can the called function use the memory for other purposes, too?\n<\/p>\n<p>\nYou sort of already know the answer to this question.\nConsider this function:\n<\/p>\n<pre>\nvoid testfunction(int a)\n{\n a = 42;\n}\n<\/pre>\n<p>\nHow would a na&iuml;ve compiler generate code for this function?\n<\/p>\n<pre>\ntestfunction:\n    sub rsp, 8 ;; realign the stack\n    ;; spill all register parameters into home locations\n    mov [rsp+0x10], rcx\n    mov [rsp+0x18], rdx\n    mov [rsp+0x20], r8\n    mov [rsp+0x28], r9\n    ;; a = 42\n    mov [rsp+0x10], 42\n    ;; return\n    add rsp, 8 ;; clean up local frame\n    ret\n<\/pre>\n<p>\nObserve that after spilling the register parameters into their\nhome locations onto the stack,\nthe function modified the local variable,\nwhich updated the value in the home location.\n<\/p>\n<p>\nSince a function can arbitrarily modify a parameter,\nyou can see that a function is therefore allowed to arbitrarily\nmodify a parameter&#8217;s home location.\nAt which point you can see that an optimizing compiler might\nchoose an arbitrary value completely unrelated to the parameter.\n<\/p>\n<p>\nOur test function has only one parameter.\nWhat about the other three home registers?\n<\/p>\n<blockquote CLASS=\"q\"><p>\nThe caller is responsible for allocating space for parameters to the callee,\nand\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/ms235286.aspx\">\nmust always allocate sufficient space for the 4 register parameters<\/a>,\neven if the callee doesn&#8217;t have that many parameters.\n<\/p><\/blockquote>\n<p>\nA function can therefore treat those 32 bytes as\n<i>bonus free play<\/i>.\nThe rationale behind those 32 bytes is that it gives you a place\nto spill your inbound register\nparameters so that they will be adjacent to the\nstack-based parameters.\n(We saw how the na&iuml;ve compiler took advantage of this by\nnot trying to be clever in its function prologue and simply\nspilling all register parameters whether it needs them or not.)\n<\/p>\n<p>\nNevertheless, you are free to use them for whatever purpose you like,\nand if you&#8217;re looking at heavily-optimized code,\nyou&#8217;ll probably find that the compiler found all sorts of clever\nthings it can do with them.\nFor example, a common trick is to use them to save the nonvolatile\nregisters that the function locally uses to hold the corresponding\nparameter!\n<\/p>\n<p>\n(Did this article look familiar?\nTurns out\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2011\/03\/02\/10135747.aspx\">\nI covered this article a few years ago<\/a>,\nbut I&#8217;m senile and accidentally repeated a topic.\nAnd since I put so much effort into writing it,\nI&#8217;m going to make you suffer through it,\neven though it&#8217;s a repeat.\nHey, television programs repeat during the summer.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We saw some time ago that the x64 calling convention in Windows reserves space for the register parameters on the stack, in case the called function wants to spill them. But can the called function use the memory for other purposes, too? You sort of already know the answer to this question. Consider this function: [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-3363","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>We saw some time ago that the x64 calling convention in Windows reserves space for the register parameters on the stack, in case the called function wants to spill them. But can the called function use the memory for other purposes, too? You sort of already know the answer to this question. Consider this function: [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3363","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=3363"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/3363\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=3363"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=3363"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=3363"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}