{"id":217,"date":"2012-05-07T23:02:41","date_gmt":"2012-05-07T21:02:41","guid":{"rendered":"http:\/\/kronotai.com\/wordpress\/?p=217"},"modified":"2012-05-07T23:02:41","modified_gmt":"2012-05-07T21:02:41","slug":"modelling-overlapping-registers","status":"publish","type":"post","link":"https:\/\/kronotai.com\/wordpress\/2012\/05\/07\/modelling-overlapping-registers\/","title":{"rendered":"Modelling overlapping registers"},"content":{"rendered":"<p>\t\t\t\t<![CDATA[Overlapping registers like eax, ax, ah and al provide different views to shared data. So one could say that this is an aliasing problem (different names for the same value). A decompiler has to cope with such overlapping registers. For a more detailed description you may want to read section 3.7 of \"Static Single Assignment for Decompilation\" from Mike Van Emmerik. I will use\n\n\n<pre lang=\"asm\">\npop eax\ninc ax\nsahf # loads the content of ah into the eflags register\n<\/pre>\n\n\nas an example for the different modeling variants. To avoid the AND and shift operations for the masking I assume some pseudo functions like <code>setLowByte(base, newByteValue)<\/code>.\n\n\n<ul>\n\n\n<li>treat each register independent. This will lead to wrong semantics:<\/li>\n\n\n<\/ul>\n\n\n\n\n<pre>\neax := pop()\nax := ax + 1\nflags := inc_flags(ax)\nflags := unpack_flags(ah)\n<\/pre>\n\n\nSo the final value of flags will be <code>unpack_flags(initialValueOfAh)<\/code>. Wrong.\n\n\n<ul>\n\n\n<li>use one register (the widest) to model the registers which are parts of it:<\/li>\n\n\n<\/ul>\n\n\n\n\n<pre>\neax := pop()\neax := setLowWord(eax, getLowWord(eax) + 1)\nflags := inc_flags(getLowWord(eax))\nflags := unpack_flags(getHighByte(eax))\n<\/pre>\n\n\nThe final flags value is <code>unpack_flags(getHighByte(setLowWord(eax, getLowWord(popedValue) + 1)))<\/code>. This could be transformed by the decompiler to the desired <code>unpack_flags(getHighByte(getLowWord(popedValue) + 1))<\/code>.\nIf some parts of the widest register are not required for the computation (e.g. only ax is used) it is possible that they are undefined. With this modeling of aliased registers an artificial and unnecessary reference will stay. So <code>pop ax;inc ax;sahf<\/code> would yield:\n\n\n<pre>\neax := setLowWord(eax,pop())\neax := setLowWord(eax, getLowWord(eax) + 1)\nflags := inc_flags(getLowWord(eax))\nflags := unpack_flags(getHighByte(eax))\n<\/pre>\n\n\nHere the initial value of eax is not required but after transformation to SSA and remove of unused registers the reference will stay.\n\n\n<ul>\n\n\n<li>Each register is modeled as a separate register but there are &#8220;update assignments&#8221;.<\/li>\n\n\n<\/ul>\n\n\n\n\n<pre>\neax := pop()\nax := getLowWord(eax)\nah := getHighByte(eax)\nal := getLowByte(eax)\nax := ax + 1\nflags := inc_flags(ax)\neax := setLowWord(eax, ax)\nah := getHighByte(ax)\nal := getLowByte(ax)\nflags := unpack_flags(ah)\n<\/pre>\n\n\nHere the final value of flags would be by pure value propagation <code>unpack_flags(getHighByte(getLowWord(poppedValue) + 1))<\/code>. And for <code>pop ax;inc ax;sahf<\/code> this variant would result in:\n\n\n<pre>\nax := pop()\neax := setLowWord(eax, ax)\nah := getHighByte(eax)\nal := getLowByte(eax)\nax := ax + 1\nflags := inc_flags(ax)\neax := setLowWord(eax, ax)\nah := getHighByte(ax)\nal := getLowByte(ax)\nflags := unpack_flags(ah)\n<\/pre>\n\n\nwith a final flags value of <code>unpack_flags(getHighByte(poppedValue + 1))<\/code>. Exactly the expected value.\nNote that the update assignments do not perform the operation (+1 in our case) again and also do not change the state of the program in any other way. The only disadvantage is the larger amount of assignments which have to be generated, transformed into the SSA form but the majority will be removed since their values are unused.\nMike writes that the last variant is the best solution. Holdec also uses this solution.\n]]>\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\t\t\t\t<![CDATA[]]>\t\t <a href=\"https:\/\/kronotai.com\/wordpress\/2012\/05\/07\/modelling-overlapping-registers\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,4],"tags":[],"class_list":["post-217","post","type-post","status-publish","format-standard","hentry","category-decompiler","category-holdec"],"_links":{"self":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/posts\/217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/comments?post=217"}],"version-history":[{"count":0,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/posts\/217\/revisions"}],"wp:attachment":[{"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/media?parent=217"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/categories?post=217"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kronotai.com\/wordpress\/wp-json\/wp\/v2\/tags?post=217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}