{"id":3257,"date":"2020-12-24T11:23:11","date_gmt":"2020-12-24T03:23:11","guid":{"rendered":"https:\/\/www.aoisnow.net\/blog\/?p=3257"},"modified":"2020-12-24T11:23:11","modified_gmt":"2020-12-24T03:23:11","slug":"tont-32483-%e4%b8%ba%e4%bb%80%e4%b9%88%e6%9c%89%e6%97%b6%e6%8d%9f%e5%9d%8f%e7%9a%84%e4%ba%8c%e8%bf%9b%e5%88%b6%e6%96%87%e4%bb%b6%e4%bc%9a%e4%bb%a4%e7%b3%bb%e7%bb%9f%e6%8f%90%e7%a4%ba%e3%80%8e%e7%a8%8b","status":"publish","type":"post","link":"https:\/\/www.aoisnow.net\/blog\/archives\/3257","title":{"rendered":"TONT 32483 \u4e3a\u4ec0\u4e48\u6709\u65f6\u635f\u574f\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\u4f1a\u4ee4\u7cfb\u7edf\u63d0\u793a\u300e\u7a0b\u5e8f\u592a\u5927\uff0c\u4e0d\u80fd\u88c5\u5165\u5185\u5b58\u300f\uff1f"},"content":{"rendered":"<p>\u539f\u6587\u94fe\u63a5\uff1a<a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060130-00\/?p=32483\" target=\"_blank\" rel=\"noopener\">https:\/\/devblogs.microsoft.com\/oldnewthing\/20060130-00\/?p=32483<\/a><\/p>\n<p>\u8bd1\u6ce8\uff1a\u539f\u6587\u7b2c\u4e00\u6bb5\u6bd4\u8f83\u957f\uff0c\u4e3a\u65b9\u4fbf\u9605\u8bfb\uff0c\u8fdb\u884c\u4e86\u624b\u5de5\u62c6\u5206\u3002<\/p>\n<p>If you take a program and corrupt the header, or just take a large-ish file that isn\u2019t a program at all and give it a \u201c.exe\u201d extension, then try to run it (Warning: Save your work first!), you will typically get the error \u201cProgram too big to fit in memory\u201d. Why such a confusing error message? Why doesn\u2019t it say \u201cCorrupted program\u201d?<\/p>\n<p>\u968f\u4fbf\u627e\u4e00\u4e2a\u7a0b\u5e8f\u6765\uff0c\u7136\u540e\u628a\u5b83\u7684\u6587\u4ef6\u5934\u641e\u4e71\uff0c\u6216\u8005\u5e72\u8106\u968f\u4fbf\u62ff\u4e00\u4e2a\u633a\u5927\u7684\u3001\u4e0d\u662f\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\uff0c\u5e76\u7ed9\u5b83\u4e00\u4e2a.exe\u7684\u6269\u5c55\u540d\uff0c\u7136\u540e\u5c1d\u8bd5\u8fd0\u884c\u4e4b\uff08\u8b66\u544a\uff1a\u5148\u4fdd\u5b58\u597d\u4f60\u6b63\u5728\u8fdb\u884c\u7684\u5de5\u4f5c\uff01\uff09\uff0c\u901a\u5e38\u4f60\u4f1a\u5f97\u5230\u4e00\u6761\u9519\u8bef\u4fe1\u606f\uff1a\u300e\u7a0b\u5e8f\u592a\u5927\uff0c\u4e0d\u80fd\u88c5\u5165\u5185\u5b58\u300f\u3002\u4e3a\u4ec0\u4e48\u662f\u8fd9\u4e48\u4ee4\u4eba\u8d39\u89e3\u7684\u4e00\u6761\u9519\u8bef\u4fe1\u606f\u5462\uff1f\u4e3a\u4ec0\u4e48\u4e0d\u8bf4\u662f\u300e\u7a0b\u5e8f\u5df2\u635f\u574f\u300f\u5462\uff1f<\/p>\n<p>Because the program isn\u2019t actually corrupted. Sort of.<\/p>\n<p>\u56e0\u4e3a\u4ece\u67d0\u79cd\u610f\u4e49\u4e0a\u8bb2\uff0c\u8fd9\u4e2a\u7a0b\u5e8f\u5b9e\u9645\u4e0a\u5e76\u6ca1\u6709\u635f\u574f\u3002<\/p>\n<p>A Win32 executable file begins with a so-called \u201cMZ\u201d header, followed by a so-called \u201cPE\u201d header. If the \u201cPE\u201d header cannot be found, then the loader attempts to load the program as a Win16 executable file, which consists of an \u201cMZ\u201d header followed by an \u201cNE\u201d header. If neither a \u201cPE\u201d nor an \u201cNE\u201d header can be found after the \u201cMZ\u201d header, then the loader attempts to load the program as an MS-DOS relocatable executable. If not even an \u201cMZ\u201d header can be found, then the loader attempt to load the program as an MS-DOS non-relocatable executable (aka \u201cCOM format\u201d since this is the format of CP\/M .COM files). In pictures:<\/p>\n<p>\u4e00\u4e2a Win32 \u53ef\u6267\u884c\u6587\u4ef6\u7684\u5f00\u5934\u5305\u542b\u6240\u8c13\u7684\u300eMZ\u300f\u6587\u4ef6\u5934\uff0c\u7d27\u8ddf\u7740\u662f\u6240\u8c13\u7684\u300ePE\u300f\u5934\u3002\u5982\u679c\u627e\u4e0d\u5230PE\u5934\uff0c\u90a3\u4e48\u52a0\u8f7d\u5668\u5c31\u4f1a\u5c1d\u8bd5\u5c06\u7a0b\u5e8f\u6309\u7167 Win16 \u53ef\u6267\u884c\u6587\u4ef6\u8fdb\u884c\u8bfb\u53d6\uff0c\u800c Win16 \u7684\u6587\u4ef6\u5934\u4fbf\u662fMZ\u540e\u9762\u8ddf\u4e00\u4e2aNE\u3002\u5982\u679c\u5728MZ\u5934\u4e4b\u540e\u65e2\u6ca1\u6709\u627e\u5230PE\u5934\uff0c\u4e5f\u6ca1\u6709\u627e\u5230NE\u5934\uff0c\u90a3\u4e48\u52a0\u8f7d\u5668\u4f1a\u5c1d\u8bd5\u5c06\u7a0b\u5e8f\u6309\u7167MS-DOS\u53ef\u91cd\u5b9a\u4f4d\u53ef\u6267\u884c\u6587\u4ef6\u8fdb\u884c\u52a0\u8f7d\u3002\u5982\u679c\u8fdeMZ\u5934\u90fd\u6ca1\u627e\u5230\uff0c\u90a3\u4e48\u52a0\u8f7d\u5668\u5c31\u4f1a\u5c06\u5176\u6309\u7167MS-DOS\u4e0d\u53ef\u91cd\u5b9a\u4f4d\u53ef\u6267\u884c\u6587\u4ef6\uff08\u4e5f\u53eb\u505aCOM\u683c\u5f0f\uff0c\u56e0\u4e3a\u8fd9\u662fCP\/M\u7684.COM\u6587\u4ef6\u7684\u683c\u5f0f\uff09\u8fdb\u884c\u52a0\u8f7d\u3002\u603b\u7684\u6765\u8bf4\u5c31\u662f\uff1a<\/p>\n<table border=\"1\">\n<tbody>\n<tr>\n<td rowspan=\"3\">MZ<\/td>\n<td>PE<\/td>\n<td>Win32<\/td>\n<\/tr>\n<tr>\n<td>NE<\/td>\n<td>Win16<\/td>\n<\/tr>\n<tr>\n<td>\u5176\u5b83\u60c5\u51b5<\/td>\n<td>MS-DOS \u53ef\u91cd\u5b9a\u4f4d\u53ef\u6267\u884c\u6587\u4ef6<\/td>\n<\/tr>\n<tr>\n<td colspan=\"2\">\u5176\u5b83\u60c5\u51b5<\/td>\n<td>MS-DOS \u4e0d\u53ef\u91cd\u5b9a\u4f4d\u53ef\u6267\u884c\u6587\u4ef6<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Observe that no matter what path you take through the chart, you will always end up at something. There is no exit path that says \u201cCorrupted program\u201d. But where does \u201cProgram too big to fit in memory\u201d come from?<\/p>\n<p>\u5f88\u660e\u663e\uff0c\u6839\u636e\u4e0a\u9762\u8868\u683c\u4e2d\u5217\u51fa\u7684\u60c5\u51b5\uff0c\u4e0d\u7ba1\u8d70\u54ea\u6761\u8def\u6700\u540e\u90fd\u4f1a\u5230\u8fbe\u67d0\u4e2a\u7ec8\u70b9\uff0c\u5e76\u4e14\u5e76\u6ca1\u6709\u54ea\u4e2a\u7ec8\u70b9\u662f\u663e\u793a\u300e\u7a0b\u5e8f\u5df2\u635f\u574f\u300f\u8fd9\u6761\u6d88\u606f\u7684\u9009\u9879\u3002\u8bdd\u8bf4\u56de\u6765\uff0c\u300e\u7a0b\u5e8f\u592a\u5927\uff0c\u65e0\u6cd5\u8f7d\u5165\u5185\u5b58\u300f\u53c8\u662f\u600e\u4e48\u56de\u4e8b\u5462\uff1f<\/p>\n<p>If the program header is corrupted, then various fields in the header such as those which specify the amount of memory required by the program will typically be nonsensical values. The loader sees an MS-DOS relocatable program that requires 800KB of conventional memory, and that\u2019s where \u201cOut of memory\u201d comes from. An MS-DOS non-relocatable program contains no such information about memory requirements. The rule for loading non-relocatable programs is simply to load the program into a single 64KB chunk of memory and set it on its way. Therefore, a program with no \u201cMZ\u201d header but which is larger than 64KB in size won\u2019t fit in the single 64KB chunk and consequently results in an \u201cOut of memory\u201d error.<\/p>\n<p>\u5982\u679c\u67d0\u4e2a\u7a0b\u5e8f\u7684\u6587\u4ef6\u5934\u635f\u574f\u4e86\uff0c\u90a3\u4e48\u5728\u6587\u4ef6\u5934\u4e2d\u7684\u4e00\u4e9b\u5b57\u6bb5\u2014\u2014\u4f8b\u5982\u6307\u5b9a\u7a0b\u5e8f\u6240\u9700\u5185\u5b58\u6570\u91cf\u7684\u503c\u901a\u5e38\u4f1a\u662f\u4e00\u4e9b\u6beb\u65e0\u610f\u4e49\u7684\u6570\u503c\u3002\u52a0\u8f7d\u5668\u4f1a\u5c06\u5176\u89c6\u4e3a\u4e00\u4e2a\u8bf7\u6c42800KB\u5e38\u89c4\u5185\u5b58\u7684 MS-DOS \u53ef\u91cd\u5b9a\u4f4d\u5e94\u7528\u7a0b\u5e8f\uff08\u8bd1\u6ce8\uff1a\u5e38\u89c4\u5185\u5b58\u4e0a\u9650\u4e3a640KB\uff09\uff0c\u800c\u8fd9\u5c31\u662f\u300e\u5185\u5b58\u4e0d\u8db3\u300f\u6d88\u606f\u7684\u6765\u6e90\u3002MS-DOS \u4e0d\u53ef\u91cd\u5b9a\u4f4d\u5e94\u7528\u7a0b\u5e8f\u662f\u4e0d\u5305\u542b\u7c7b\u4f3c\u6240\u9700\u5185\u5b58\u6570\u91cf\u4e4b\u7c7b\u7684\u4fe1\u606f\u7684\uff0c\u52a0\u8f7d\u8fd9\u7c7b\u7a0b\u5e8f\u7684\u8def\u5b50\uff0c\u5c31\u662f\u5c06\u5176\u88c5\u5165\u5355\u72ec\u4e00\u6bb564KB\u5185\u5b58\u5e76\u8fd0\u884c\u5b83\u3002\u56e0\u6b64\uff0c\u4e00\u4e2a\u6ca1\u6709MZ\u5934\u3001\u4f46\u662f\u5c3a\u5bf8\u53c8\u6bd464KB\u5927\u7684\u7a0b\u5e8f\u81ea\u7136\u65e0\u6cd5\u88c5\u516564KB\u7684\u5185\u5b58\u6bb5\uff0c\u7531\u6b64\u5f15\u53d1\u4e86\u300e\u5185\u5b58\u4e0d\u8db3\u300f\u7684\u9519\u8bef\u3002<\/p>\n<p>And since people are certain to ask:<\/p>\n<p>\u987a\u4fbf\u4e00\u63d0\u5427\uff0c\u53cd\u6b63\u80af\u5b9a\u4f1a\u6709\u4eba\u95ee\uff1a<\/p>\n<p>\u201cMZ\u201d = the legendary Mark Zbikowski.<\/p>\n<p>MZ\uff1a\u4f20\u5947\u4eba\u7269\u00a0Mark Zbikowski \u7684\u7f29\u5199\uff08\u8bd1\u6ce8\uff1a\u5fae\u8f6f\u516c\u53f8\u7684\u5143\u8001\u7ea7\u5f00\u53d1\u8005\uff09<\/p>\n<p>\u201cNE\u201d = \u201cNew Executable\u201d, back when Windows was \u201cnew\u201d.<\/p>\n<p>NE\uff1a\u65b0\u5f0f\u53ef\u6267\u884c\u7a0b\u5e8f\uff08New Executable\uff09\u7684\u7f29\u5199\uff0c\u90a3\u65f6\u5019 Windows \u8fd8\u86ee\u300e\u65b0\u300f\u7684\u3002<\/p>\n<p>\u201cPE\u201d = \u201cPortable Executable\u201d, because one of Windows NT\u2019s claims to fame was its portability to architectures other than the x86.<\/p>\n<p>PE\uff1a\u4fbf\u643a\u5f0f\u53ef\u6267\u884c\u7a0b\u5e8f\uff08Portable Executable\uff09\u7684\u7f29\u5199\uff0c\u56e0\u4e3a Windows NT \u51fa\u540d\u7684\u539f\u56e0\u4e4b\u4e00\u5c31\u662f\u5176\u53ef\u4ee5\u5728 x86 \u5e73\u53f0\u4e4b\u5916\u7684\u53ef\u79fb\u690d\u6027\u3002<\/p>\n<p>\u201cLE\u201d = \u201cLinear Executable\u201d, used by OS\/2 and by Windows 95 device drivers.<\/p>\n<p>LE\uff1a\u7ebf\u6027\u53ef\u6267\u884c\u7a0b\u5e8f\uff08Linear Executable\uff09\uff0c\u7531 OS\/2 \u548c Windows 95 \u7684\u9a71\u52a8\u7a0b\u5e8f\u6240\u4f7f\u7528\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u539f\u6587\u94fe\u63a5\uff1ahttps:\/\/devblogs.microsoft.com\/oldnewthing\/2006013 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-3257","post","type-post","status-publish","format-standard","hentry","category-tont_history"],"_links":{"self":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/posts\/3257","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/comments?post=3257"}],"version-history":[{"count":0,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/posts\/3257\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/media?parent=3257"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/categories?post=3257"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aoisnow.net\/blog\/wp-json\/wp\/v2\/tags?post=3257"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}