{"id":1295,"date":"2022-11-13T15:12:29","date_gmt":"2022-11-13T07:12:29","guid":{"rendered":"https:\/\/www.mustenaka.cn\/?p=1295"},"modified":"2022-11-16T22:54:41","modified_gmt":"2022-11-16T14:54:41","slug":"plan-a-manual-for-the-plan-9-assembler-learn","status":"publish","type":"post","link":"https:\/\/www.mustenaka.cn\/index.php\/2022\/11\/13\/plan-a-manual-for-the-plan-9-assembler-learn\/","title":{"rendered":"Plan 9\u6c47\u7f16\u5668\u624b\u518c"},"content":{"rendered":"<p><span><b>A Manual for the Plan 9 assembler\uff08Plan 9 \u6c47\u7f16\u624b\u518c\uff09<\/b><\/span><\/p>\n<blockquote><p><span><i>\u4f5c\u8005\uff1aRob Pike<\/i><\/span><\/p>\n<p><span><i>rob@plan9.bell-labs.com<\/i><\/span><\/p>\n<p>\u7ffb\u8bd1\uff1aMustenaka<\/p><\/blockquote>\n<p>Plan9\u662fGolang\u6c47\u7f16\u8bed\u8a00\uff0c\u662f\u8fdb\u5165\u9ad8\u7ea7Golang\u89e3\u51b3\u5404\u79cddebug\u95ee\u9898\u7684\u5fc5\u7ecf\u4e4b\u8def\uff0c\u672c\u6587\u4e3b\u8981\u7ffb\u8bd1Plan9\u7684\u4f7f\u7528\u624b\u518c\uff0c\u5e76\u589e\u52a0\u4e00\u4e9b\u81ea\u5df1\u7684\u770b\u6cd5\u548c\u7b80\u4ecb\uff0c\u539f\u6587\u5730\u5740<a href=\"https:\/\/9p.io\/sys\/doc\/asm.html\">https:\/\/9p.io\/sys\/doc\/asm.html<\/a><\/p>\n<p><span><b>Machines<\/b><\/span><\/p>\n<p><span>There is an assembler for each of the MIPS, SPARC, Intel 386, AMD64, Power PC, and ARM. The 68020 assembler,\u00a0<\/span><span><tt>2a<\/tt><\/span><span>, (no longer distributed) is the oldest and in many ways the prototype. The assemblers are really just variations of a single program: they share many properties such as left-to-right assignment order for instruction operands and the synthesis of macro instructions such as\u00a0<\/span><span><tt>MOVE<\/tt><\/span><span>\u00a0to hide the peculiarities of the load and store structure of the machines. To keep things concrete, the first part of this manual is specifically about the 68020. At the end is a description of the differences among the other assemblers.<\/span><\/p>\n<p>\u6bcf\u4e2a MIPS\u3001SPARC\u3001Intel 386\u3001AMD64\u3001Power PC \u548c ARM \u90fd\u6709\u4e00\u4e2a\u6c47\u7f16\u5668\u3002 68020 \u6c47\u7f16\u5668 \uff0c2a\uff08\u4e0d\u518d\u5206\u53d1\uff09\u662f\u6700\u53e4\u8001\u7684\uff0c\u5e76\u4e14\u5728\u8bb8\u591a\u65b9\u9762\u90fd\u662f\u539f\u578b\u3002 \u6c47\u7f16\u7a0b\u5e8f\u5b9e\u9645\u4e0a\u53ea\u662f\u5355\u4e2a\u7a0b\u5e8f\u7684\u53d8\u4f53\uff1a\u5b83\u4eec\u5171\u4eab\u8bb8\u591a\u5c5e\u6027\uff0c\u4f8b\u5982\u6307\u4ee4\u64cd\u4f5c\u6570\u4ece\u5de6\u5230\u53f3\u7684\u5206\u914d\u987a\u5e8f\u548c\u5b8f\u6307\u4ee4\u7684\u5408\u6210\uff0c\u4f8b\u5982 MOVE \u4ee5\u9690\u85cf\u673a\u5668\u52a0\u8f7d\u548c\u5b58\u50a8\u7ed3\u6784\u7684\u7279\u6027\u3002 \u4e3a\u4e86\u5177\u4f53\u8d77\u89c1\uff0c\u672c\u624b\u518c\u7684\u7b2c\u4e00\u90e8\u5206\u4e13\u95e8\u9488\u5bf9 68020\u3002\u6700\u540e\u662f\u5bf9\u5176\u4ed6\u6c47\u7f16\u5668\u4e4b\u95f4\u5dee\u5f02\u7684\u63cf\u8ff0\u3002<\/p>\n<blockquote><p>\u6ce8\uff1a68020\u6307\u7684\u662f1984\u5e74\u6469\u6258\u7f57\u62c9\u53d1\u5e03\u768432\u4f4dcpu\uff0c\u6539\u8fdb\u4e86\u65e9\u4e9b\u65f6\u5019\u768416\u4f4dcpu\u548c24\u4f4dcpu\u7684\u7f3a\u9677\u95ee\u9898\uff0c\u4e00\u5ea6\u6d41\u884c\u6210\u4e3a\u4e00\u79cd\u6807\u51c6\uff0c\u540e\u57fa\u4e8e\u6b64\u7684\u6c47\u7f16\u5668\u6f14\u53d8\u53d1\u5c55\u51fa\u4e86\u5404\u4e2a\u65b0\u578b\u7f16\u8bd1\u5668\u3002<\/p><\/blockquote>\n<p><span><b>Registers<\/b><\/span><\/p>\n<p><span>All pre-defined symbols in the assembler are upper-case. Data registers are\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>R7<\/tt><\/span><span>; address registers are\u00a0<\/span><span><tt>A0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>A7<\/tt><\/span><span>; floating-point registers are\u00a0<\/span><span><tt>F0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>F7<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u4e2d\u7684\u6240\u6709\u9884\u5b9a\u4e49\u7b26\u53f7\u90fd\u662f\u5927\u5199\u7684\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6570\u636e\u5bc4\u5b58\u5668\u662fR0\u5230R7; <\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5730\u5740\u5bc4\u5b58\u5668\u4e3aA0\u5230A7; <\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u6d6e\u70b9\u5bc4\u5b58\u5668\u4eceF0\u5230F7\u3002<\/span><\/p>\n<p><span>A pointer in\u00a0<\/span><span><tt>A6<\/tt><\/span><span>\u00a0is used by the C compiler to point to data, enabling short addresses to be used more often. The value of\u00a0<\/span><span><tt>A6<\/tt><\/span><span>\u00a0is constant and must be set during C program initialization to the address of the externally-defined symbol\u00a0<\/span><span><tt>a6base<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">A6\u4e2d\u7684\u6307\u9488\u88abC\u7f16\u8bd1\u5668\u7528\u6765\u6307\u5411\u6570\u636e\uff0c\u4f7f\u77ed\u5730\u5740\u66f4\u7ecf\u5e38\u5730\u88ab\u4f7f\u7528\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">A6\u7684\u503c\u662f\u6052\u5b9a\u7684\uff0c\u5fc5\u987b\u5728C\u7a0b\u5e8f\u521d\u59cb\u5316\u65f6\u8bbe\u7f6e\u4e3a\u5916\u90e8\u5b9a\u4e49\u7684\u7b26\u53f7a6base\u7684\u5730\u5740\u3002<\/span><\/p>\n<p><span>The following hardware registers are defined in the assembler; their meaning should be obvious given a 68020 manual:\u00a0<\/span><span><tt>CAAR<\/tt><\/span><span>,\u00a0<\/span><span><tt>CACR<\/tt><\/span><span>,\u00a0<\/span><span><tt>CCR<\/tt><\/span><span>,\u00a0<\/span><span><tt>DFC<\/tt><\/span><span>,\u00a0<\/span><span><tt>ISP<\/tt><\/span><span>,\u00a0<\/span><span><tt>MSP<\/tt><\/span><span>,\u00a0<\/span><span><tt>SFC<\/tt><\/span><span>,\u00a0<\/span><span><tt>SR<\/tt><\/span><span>,\u00a0<\/span><span><tt>USP<\/tt><\/span><span>, and\u00a0<\/span><span><tt>VBR<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4ee5\u4e0b\u786c\u4ef6\u5bc4\u5b58\u5668\u5728\u6c47\u7f16\u7a0b\u5e8f\u4e2d\u5b9a\u4e49;<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5bf9\u4e8e68020\u624b\u518c\uff0c\u5b83\u4eec\u7684\u542b\u4e49\u5e94\u8be5\u5f88\u660e\u663e:CAAR\u3001CACR\u3001CCR\u3001DFC\u3001ISP\u3001MSP\u3001SFC\u3001SR\u3001USP\u548cVBR\u3002<\/span><\/p>\n<p><span>The assembler also defines several pseudo-registers that manipulate the stack:\u00a0<\/span><span><tt>FP<\/tt><\/span><span>,\u00a0<\/span><span><tt>SP<\/tt><\/span><span>, and\u00a0<\/span><span><tt>TOS<\/tt><\/span><span>.\u00a0<\/span><span><tt>FP<\/tt><\/span><span>\u00a0is the frame pointer, so\u00a0<\/span><span><tt>0(FP)<\/tt><\/span><span>\u00a0is the first argument,\u00a0<\/span><span><tt>4(FP)<\/tt><\/span><span>\u00a0is the second, and so on.\u00a0<\/span><span><tt>SP<\/tt><\/span><span>\u00a0is the local stack pointer, where automatic variables are held (SP is a pseudo-register only on the 68020);\u00a0<\/span><span><tt>0(SP)<\/tt><\/span><span>\u00a0is the first automatic, and so on as with\u00a0<\/span><span><tt>FP<\/tt><\/span><span>. Finally,\u00a0<\/span><span><tt>TOS<\/tt><\/span><span>\u00a0is the top-of-stack register, used for pushing parameters to procedures, saving temporary values, and so on.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u8fd8\u5b9a\u4e49\u4e86\u51e0\u4e2a\u64cd\u4f5c\u5806\u6808\u7684\u4f2a\u5bc4\u5b58\u5668:FP\u3001SP\u548cTOS\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">FP\u662f\u5e27\u6307\u9488\uff0c\u56e0\u6b640(FP)\u662f\u7b2c\u4e00\u4e2a\u53c2\u6570\uff0c4(FP)\u662f\u7b2c\u4e8c\u4e2a\u53c2\u6570\uff0c\u4f9d\u6b64\u7c7b\u63a8\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">SP\u662f\u672c\u5730\u5806\u6808\u6307\u9488\uff0c\u5176\u4e2d\u4fdd\u5b58\u81ea\u52a8\u53d8\u91cf(SP\u662f\u53ea\u572868020\u4e0a\u7684\u4f2a\u5bc4\u5b58\u5668);<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">0(SP)\u662f\u7b2c\u4e00\u4e2a\u81ea\u52a8\uff0c\u4ee5\u6b64\u7c7b\u63a8\uff0cFP\u4e5f\u662f\u5982\u6b64\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u6700\u540e\uff0cTOS\u662f\u6808\u9876\u5bc4\u5b58\u5668\uff0c\u7528\u4e8e\u5c06\u53c2\u6570\u63a8\u5165\u8fc7\u7a0b\u3001\u4fdd\u5b58\u4e34\u65f6\u503c\u7b49\u7b49\u3002<\/span><\/p>\n<p><span>The assembler and loader track these pseudo-registers so the above statements are true regardless of what has been pushed on the hardware stack, pointed to by\u00a0<\/span><span><tt>A7<\/tt><\/span><span>. The name\u00a0<\/span><span><tt>A7<\/tt><\/span><span>\u00a0refers to the hardware stack pointer, but beware of mixed use of\u00a0<\/span><span><tt>A7<\/tt><\/span><span>\u00a0and the above stack-related pseudo-registers, which will cause trouble. Note, too, that the\u00a0<\/span><span><tt>PEA<\/tt><\/span><span>\u00a0instruction is observed by the loader to alter SP and thus will insert a corresponding pop before all returns. The assembler accepts a label-like name to be attached to\u00a0<\/span><span><tt>FP<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>SP<\/tt><\/span><span>\u00a0uses, such as\u00a0<\/span><span><tt>p+0(FP)<\/tt><\/span><span>, to help document that\u00a0<\/span><span><tt>p<\/tt><\/span><span>\u00a0is the first argument to a routine. The name goes in the symbol table but has no significance to the result of the program.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u5668\u548c\u52a0\u8f7d\u5668\u8ddf\u8e2a\u8fd9\u4e9b\u4f2a\u5bc4\u5b58\u5668\uff0c\u56e0\u6b64\u65e0\u8bba\u786c\u4ef6\u5806\u6808\u4e0a\u63a8\u9001\u4e86\u4ec0\u4e48\uff0c\u4e0a\u9762\u7684\u8bed\u53e5\u90fd\u662f\u6b63\u786e\u7684\uff0cA7\u6307\u51fa\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u540d\u79f0A7\u6307\u7684\u662f\u786c\u4ef6\u5806\u6808\u6307\u9488\uff0c\u4f46\u8981\u6ce8\u610f\u6df7\u5408\u4f7f\u7528A7\u548c\u4e0a\u9762\u4e0e\u5806\u6808\u76f8\u5173\u7684\u4f2a\u5bc4\u5b58\u5668\uff0c\u8fd9\u4f1a\u5e26\u6765\u9ebb\u70e6\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u8fd8\u8981\u6ce8\u610f\uff0c\u52a0\u8f7d\u5668\u4f1a\u89c2\u5bdfPEA\u6307\u4ee4\u6765\u6539\u53d8SP\uff0c\u56e0\u6b64\u4f1a\u5728\u6240\u6709\u8fd4\u56de\u4e4b\u524d\u63d2\u5165\u76f8\u5e94\u7684pop\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u63a5\u53d7\u4e00\u4e2a\u6807\u7b7e\u5f0f\u7684\u540d\u79f0\u9644\u52a0\u5230FP\u4e0a\uff0cSP\u4f7f\u7528(\u4f8b\u5982p+0(FP))\u6765\u5e2e\u52a9\u8bf4\u660ep\u662f\u4f8b\u7a0b\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u540d\u79f0\u8fdb\u5165\u7b26\u53f7\u8868\uff0c\u4f46\u5bf9\u7a0b\u5e8f\u7684\u7ed3\u679c\u6ca1\u6709\u610f\u4e49\u3002<\/span><\/p>\n<blockquote><p>PS\uff1a\u7406\u89e3\u4e00\u4e0b\u5c31\u662f<\/p>\n<p><code>R0              \u6570\u636e\u5bc4\u5b58\u5668<br \/>\n<\/code><\/p>\n<p><code>A0              \u5730\u5740\u5bc4\u5b58\u5668<br \/>\n<\/code><\/p>\n<p><code>F0              \u6d6e\u70b9\u5bc4\u5b58\u5668<br \/>\n<\/code><\/p>\n<p><code>CAAR, CACR, \u7b49\u7279\u6b8a\u540d\u5b57<br \/>\n<\/code><\/p>\n<p><code>$con            \u5e38\u91cf<br \/>\n<\/code><\/p>\n<p><code>$fcon           \u6d6e\u70b9\u6570\u5e38\u91cf<br \/>\n<\/code><\/p>\n<p><code>name+o(SB)      \u5916\u90e8\u7b26\u53f7<br \/>\n<\/code><\/p>\n<p><code>name&lt;&gt;+o(SB)    \u5c40\u90e8\u7b26\u53f7<br \/>\n<\/code><\/p>\n<p><code>name+o(SP)      \u81ea\u52a8\u7b26\u53f7<br \/>\n<\/code><\/p>\n<p><code>name+o(FP)      \u5b9e\u9645\u53c2\u6570<br \/>\n<\/code><\/p>\n<p><code>$name+o(SB)     \u5916\u90e8\u5730\u5740<br \/>\n<\/code><\/p>\n<p><code>$name&lt;&gt;+o(SB)   \u5c40\u90e8\u5730\u5740<br \/>\n<\/code><\/p>\n<p><code>(A0)+           \u95f4\u63a5\u540e\u589e\u91cf<br \/>\n<\/code><\/p>\n<p><code>-(A0)           \u95f4\u63a5\u524d\u589e\u91cf<br \/>\n<\/code><\/p>\n<p><code>o(A0)<br \/>\n<\/code><\/p>\n<p><code>o()(R0.s)<\/code><\/p><\/blockquote>\n<p><span><b>Referring to data<\/b><\/span><\/p>\n<p><span>All external references must be made relative to some pseudo-register, either\u00a0<\/span><span><tt>PC<\/tt><\/span><span>\u00a0(the virtual program counter) or\u00a0<\/span><span><tt>SB<\/tt><\/span><span>\u00a0(the \u2018\u2018static base\u2019\u2019 register).\u00a0<\/span><span><tt>PC<\/tt><\/span><span>\u00a0counts instructions, not bytes of data. For example, to branch to the second following instruction, that is, to skip one instruction, one may write<\/span><\/p>\n<p>\u6240\u6709\u5916\u90e8\u5f15\u7528\u90fd\u5fc5\u987b\u76f8\u5bf9\u4e8e\u67d0\u4e9b\u4f2a\u5bc4\u5b58\u5668\u8fdb\u884c\uff0cPC\uff08\u865a\u62df\u7a0b\u5e8f\u8ba1\u6570\u5668\uff09\u6216 SB\uff08\u201c\u9759\u6001\u57fa\u201d\u5bc4\u5b58\u5668\uff09\u3002 PC \u8ba1\u7b97\u6307\u4ee4\uff0c\u800c\u4e0d\u662f\u6570\u636e\u5b57\u8282\u3002\u4f8b\u5982\uff0c\u8df3\u8f6c\u5230\u7b2c\u4e8c\u6761\u6307\u4ee4\uff0c\u5373\u8df3\u8fc7\u4e00\u6761\u6307\u4ee4\uff0c\u53ef\u4ee5\u8fd9\u6837\u5199<\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0BRA\u00a02(PC)<\/tt><\/span><\/p>\n<p><span>Labels are also allowed, as in<\/span><\/p>\n<p><span>\u6807\u7b7e\u4e5f\u662f\u5141\u8bb8\u7684\uff0c\u6bd4\u5982<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0BRA\u00a0return<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0NOP<\/tt><\/span><\/p>\n<p><span><tt>return:<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0RTS<\/tt><\/span><\/p>\n<p><span>When using labels, there is no\u00a0<\/span><span><tt>(PC)<\/tt><\/span><span>\u00a0annotation.<\/span><\/p>\n<p><span>\u5f53\u4f7f\u7528\u6807\u7b7e\u65f6\uff0c\u6ca1\u6709(PC)\u6ce8\u91ca\u3002<\/span><\/p>\n<p><span>The pseudo-register\u00a0<\/span><span><tt>SB<\/tt><\/span><span>\u00a0refers to the beginning of the address space of the program. Thus, references to global data and procedures are written as offsets to\u00a0<\/span><span><tt>SB<\/tt><\/span><span>, as in<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4f2a\u5bc4\u5b58\u5668SB\u6307\u7684\u662f\u7a0b\u5e8f\u5730\u5740\u7a7a\u95f4\u7684\u5f00\u5934\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u56e0\u6b64\uff0c\u5bf9\u5168\u5c40\u6570\u636e\u548c\u8fc7\u7a0b\u7684\u5f15\u7528\u88ab\u5199\u5165SB\u7684\u504f\u79fb\u91cf\uff0c\u5982<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0$array(SB),\u00a0TOS<\/tt><\/span><\/p>\n<p><span>to push the address of a global array on the stack, or<\/span><\/p>\n<p><span>\u5c06\u5168\u5c40\u6570\u7ec4\u7684\u5730\u5740\u63a8\u5165\u5806\u6808\uff0c\u6216<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0array+4(SB),\u00a0TOS<\/tt><\/span><\/p>\n<p><span>to push the second (4-byte) element of the array. Note the use of an offset; the complete list of addressing modes is given below. Similarly, subroutine calls must use\u00a0<\/span><span><tt>SB<\/tt><\/span><span>:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u63a8\u5165\u6570\u7ec4\u7684\u7b2c\u4e8c\u4e2a(4\u5b57\u8282)\u5143\u7d20\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6ce8\u610f\u504f\u79fb\u91cf\u7684\u4f7f\u7528;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4e0b\u9762\u7ed9\u51fa\u4e86\u5bfb\u5740\u6a21\u5f0f\u7684\u5b8c\u6574\u5217\u8868\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u7c7b\u4f3c\u5730\uff0c\u5b50\u4f8b\u7a0b\u8c03\u7528\u5fc5\u987b\u4f7f\u7528SB:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0BSR\u00a0exit(SB)<\/tt><\/span><\/p>\n<p><span>File-static variables have syntax<\/span><\/p>\n<p><span>\u6587\u4ef6\u9759\u6001\u53d8\u91cf\u6709\u8bed\u6cd5<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0local&lt;&gt;+4(SB)<\/tt><\/span><\/p>\n<p><span>The\u00a0<\/span><span><tt>&lt;&gt;<\/tt><\/span><span>\u00a0will be filled in at load time by a unique integer.<\/span><\/p>\n<p>&lt;&gt;\u5c06<span>\u5728\u52a0\u8f7d\u65f6\u7531\u4e00\u4e2a\u552f\u4e00\u7684\u6574\u6570\u586b\u5145\u3002<\/span><\/p>\n<p><span>When a program starts, it must execute<\/span><\/p>\n<p><span>\u5f53\u7a0b\u5e8f\u542f\u52a8\u65f6\uff0c\u5b83\u5fc5\u987b\u6267\u884c<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0$a6base(SB),\u00a0A6<\/tt><\/span><\/p>\n<p><span>before accessing any global data. (On machines such as the MIPS and SPARC that cannot load a register in a single instruction, constants are loaded through the static base register. The loader recognizes code that initializes the static base register and treats it specially. You must be careful, however, not to load large constants on such machines when the static base register is not set up, such as early in interrupt routines.)<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5728\u8bbf\u95ee\u4efb\u4f55\u5168\u5c40\u6570\u636e\u4e4b\u524d\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">(\u5728MIPS\u548cSPARC\u7b49\u4e0d\u80fd\u5728\u5355\u4e2a\u6307\u4ee4\u4e2d\u52a0\u8f7d\u5bc4\u5b58\u5668\u7684\u673a\u5668\u4e0a\uff0c\u5e38\u91cf\u901a\u8fc7\u9759\u6001\u57fa\u5bc4\u5b58\u5668\u52a0\u8f7d\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u8bc6\u522b\u521d\u59cb\u5316\u9759\u6001\u57fa\u5bc4\u5b58\u5668\u7684\u4ee3\u7801\u5e76\u5bf9\u5176\u8fdb\u884c\u7279\u6b8a\u5904\u7406\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u4f46\u662f\uff0c\u4f60\u5fc5\u987b\u5c0f\u5fc3\uff0c\u4e0d\u8981\u5728\u9759\u6001\u57fa\u5bc4\u5b58\u5668\u6ca1\u6709\u8bbe\u7f6e\u7684\u60c5\u51b5\u4e0b\u5728\u8fd9\u6837\u7684\u673a\u5668\u4e0a\u52a0\u8f7d\u5927\u7684\u5e38\u91cf\uff0c\u4f8b\u5982\u5728\u4e2d\u65ad\u4f8b\u7a0b\u7684\u65e9\u671f\u3002)<\/span><\/p>\n<p><span><b>Expressions<\/b><\/span><\/p>\n<p><span>Expressions are mostly what one might expect. Where an offset or a constant is expected, a primary expression with unary operators is allowed. A general C constant expression is allowed in parentheses.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4eba\u4eec\u60f3\u8981\u7684\u5927\u591a\u662f\u201c\u8868\u8fbe\u5f0f\u201d\uff0c<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5982\u679c\u9700\u8981\u504f\u79fb\u91cf\u6216\u5e38\u91cf\uff0c\u5219\u5141\u8bb8\u4f7f\u7528\u5e26\u4e00\u5143\u8fd0\u7b97\u7b26\u7684\u4e3b\u8868\u8fbe\u5f0f\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4e00\u822c\u7684C\u8bed\u8a00\u5e38\u91cf\u8868\u8fbe\u5f0f\u5141\u8bb8\u5728\u62ec\u53f7\u4e2d\u3002<\/span><\/p>\n<p><span>Source files are preprocessed exactly as in the C compiler, so\u00a0<\/span><span><tt>#define<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>#include<\/tt><\/span><span>\u00a0work.<\/span><\/p>\n<p><span>\u6e90\u6587\u4ef6\u7684\u9884\u5904\u7406\u4e0eC\u8bed\u8a00\u7f16\u8bd1\u5668\u4e2d\u7684\u5b8c\u5168\u76f8\u540c\uff0c\u56e0\u6b64\u53ef\u4ee5\u4f7f\u7528\u8fd0\u884c#define\u548c#include\u3002<\/span><\/p>\n<p><span><b>Addressing modes<\/b><\/span><\/p>\n<p><span>The simple addressing modes are shared by all the assemblers. Here, for completeness, follows a table of all the 68020 addressing modes, since that machine has the richest set. In the table,\u00a0<\/span><span><tt>o<\/tt><\/span><span>\u00a0is an offset, which if zero may be elided, and\u00a0<\/span><span><tt>d<\/tt><\/span><span>\u00a0is a displacement, which is a constant between -128 and 127 inclusive. Many of the modes listed have the same name; scrutiny of the format will show what default is being applied. For instance, indexed mode with no address register supplied operates as though a zero-valued register were used. For &#8220;offset&#8221; read &#8220;displacement.&#8221; For &#8220;<\/span><span><tt>.s<\/tt><\/span><span>&#8221; read one of\u00a0<\/span><span><tt>.L<\/tt><\/span><span>, or\u00a0<\/span><span><tt>.W<\/tt><\/span><span>\u00a0followed by\u00a0<\/span><span><tt>*1<\/tt><\/span><span>,\u00a0<\/span><span><tt>*2<\/tt><\/span><span>,\u00a0<\/span><span><tt>*4<\/tt><\/span><span>, or\u00a0<\/span><span><tt>*8<\/tt><\/span><span>\u00a0to indicate the size and scaling of the data.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6240\u6709\u6c47\u7f16\u7a0b\u5e8f\u5171\u4eab\u7b80\u5355\u5bfb\u5740\u6a21\u5f0f\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u8fd9\u91cc\uff0c\u4e3a\u4e86\u5b8c\u6574\u8d77\u89c1\uff0c\u4e0b\u9762\u662f\u4e00\u4e2a\u5305\u542b\u6240\u670968020\u5bfb\u5740\u6a21\u5f0f\u7684\u8868\uff0c\u56e0\u4e3a\u90a3\u53f0\u673a\u5668\u7684\u5bfb\u5740\u6a21\u5f0f\u6700\u4e30\u5bcc\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5728\u8868\u4e2d\uff0co\u662f\u4e00\u4e2a\u504f\u79fb\u91cf\uff0c\u5982\u679c0\u53ef\u4ee5\u7701\u7565\uff0cd\u662f\u4e00\u4e2a\u4f4d\u79fb\uff0c\u5b83\u662f-128\u5230127\u4e4b\u95f4\u7684\u4e00\u4e2a\u5e38\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u5217\u51fa\u7684\u8bb8\u591a\u6a21\u5f0f\u90fd\u6709\u76f8\u540c\u7684\u540d\u79f0;<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u4ed4\u7ec6\u68c0\u67e5\u683c\u5f0f\u5c06\u663e\u793a\u5e94\u7528\u4e86\u4ec0\u4e48\u9ed8\u8ba4\u503c\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c\u6ca1\u6709\u63d0\u4f9b\u5730\u5740\u5bc4\u5b58\u5668\u7684\u7d22\u5f15\u6a21\u5f0f\u5c31\u50cf\u4f7f\u7528\u4e86\u96f6\u503c\u5bc4\u5b58\u5668\u4e00\u6837\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u5bf9\u4e8e\u201coffset\u201d\uff0c\u8bf7\u9605\u8bfb\u201cdisplacement\u201d\u3002<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">\u201d\u3002<\/span><span data-section=\"0\" data-sentence=\"8\" data-group=\"0-8\" class=\"tgt color_text_0\">s\u201d\u8bfb\u53d6. l\u6216. w\u540e\u9762\u8ddf\u7740*1\u3001*2\u3001*4\u6216*8\u4e2d\u7684\u4e00\u4e2a\uff0c\u4ee5\u8868\u793a\u6570\u636e\u7684\u5927\u5c0f\u548c\u4f38\u7f29\u3002<\/span><\/p>\n<p><center><img decoding=\"async\" src=\"https:\/\/9p.io\/sys\/doc\/asm0.png\" class=\"aligncenter\" \/><\/center><span><b>Laying down data<\/b><\/span><\/p>\n<p><span>Placing data in the instruction stream, say for interrupt vectors, is easy: the pseudo-instructions\u00a0<\/span><span><tt>LONG<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>WORD<\/tt><\/span><span>\u00a0(but not\u00a0<\/span><span><tt>BYTE<\/tt><\/span><span>) lay down the value of their single argument, of the appropriate size, as if it were an instruction:<\/span><\/p>\n<p><span>\u5728\u6307\u4ee4\u6d41\u4e2d\u653e\u7f6e\u6570\u636e\uff0c\u6bd4\u5982\u4e2d\u65ad\u5411\u91cf\uff0c\u5f88\u5bb9\u6613:\u4f2a\u6307\u4ee4LONG\u548cWORD(\u4f46\u4e0d\u662fBYTE)\u5c06\u5b83\u4eec\u7684\u5355\u4e2a\u53c2\u6570\u7684\u503c\u8bbe\u7f6e\u4e3a\u9002\u5f53\u7684\u5927\u5c0f\uff0c\u5c31\u50cf\u4e00\u6761\u6307\u4ee4\u4e00\u6837:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0LONG\u00a0\u00a0\u00a0\u00a0$12345<\/tt><\/span><\/p>\n<p><span>places the long 12345 (base 10) in the instruction stream. (On most machines, the only such operator is\u00a0<\/span><span><tt>WORD<\/tt><\/span><span>\u00a0and it lays down 32-bit quantities. The 386 has all three:\u00a0<\/span><span><tt>LONG<\/tt><\/span><span>,\u00a0<\/span><span><tt>WORD<\/tt><\/span><span>, and\u00a0<\/span><span><tt>BYTE<\/tt><\/span><span>. The AMD64 adds\u00a0<\/span><span><tt>QUAD<\/tt><\/span><span>\u00a0to that for 64-bit values. The 960 has only one,\u00a0<\/span><span><tt>LONG<\/tt><\/span><span>.)<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5728\u6307\u4ee4\u6d41\u4e2d\u653e\u7f6e\u957f12345(\u4ee510\u4e3a\u57fa\u6570)\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0 highlight\">(\u5728\u5927\u591a\u6570\u673a\u5668\u4e0a\uff0c\u552f\u4e00\u8fd9\u6837\u7684\u64cd\u4f5c\u7b26\u662fWORD\uff0c\u5b83\u89c4\u5b9a32\u4f4d\u7684\u6570\u91cf\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">386\u5177\u5907\u6240\u6709\u4e09\u79cd\u529f\u80fd:LONG\u3001WORD\u548cBYTE\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">AMD64\u4e3a64\u4f4d\u503c\u6dfb\u52a0\u4e86QUAD\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">960\u53ea\u6709\u4e00\u4e2a\uff0cLONG\u3002)<\/span><\/p>\n<p><span>Placing information in the data section is more painful. The pseudo-instruction\u00a0<\/span><span><tt>DATA<\/tt><\/span><span>\u00a0does the work, given two arguments: an address at which to place the item, including its size, and the value to place there. For example, to define a character array\u00a0<\/span><span><tt>array<\/tt><\/span><span>\u00a0containing the characters\u00a0<\/span><span><tt>abc<\/tt><\/span><span>\u00a0and a terminating null:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5728\u6570\u636e\u90e8\u5206\u653e\u7f6e\u4fe1\u606f\u66f4\u52a0\u75db\u82e6\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u4f2a\u6307\u4ee4DATA\u5b8c\u6210\u8fd9\u9879\u5de5\u4f5c\uff0c\u7ed9\u5b9a\u4e24\u4e2a\u53c2\u6570:\u653e\u7f6e\u9879\u7684\u5730\u5740(\u5305\u62ec\u5176\u5927\u5c0f)\u548c\u653e\u7f6e\u9879\u7684\u503c\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c\u5b9a\u4e49\u4e00\u4e2a\u5305\u542b\u5b57\u7b26abc\u548c\u7ed3\u675f\u7b26null\u7684\u5b57\u7b26\u6570\u7ec4:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0DATA\u00a0\u00a0\u00a0\u00a0array+0(SB)\/1,\u00a0$\u2019a\u2019<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0DATA\u00a0\u00a0\u00a0\u00a0array+1(SB)\/1,\u00a0$\u2019b\u2019<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0DATA\u00a0\u00a0\u00a0\u00a0array+2(SB)\/1,\u00a0$\u2019c\u2019<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0GLOBL\u00a0\u00a0\u00a0array(SB),\u00a0$4<\/tt><\/span><\/p>\n<p><span>or<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0DATA\u00a0\u00a0\u00a0\u00a0array+0(SB)\/4,\u00a0$\"abc\\z\"<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0GLOBL\u00a0\u00a0\u00a0array(SB),\u00a0$4<\/tt><\/span><\/p>\n<p><span>The\u00a0<\/span><span><tt>\/1<\/tt><\/span><span>\u00a0defines the number of bytes to define,\u00a0<\/span><span><tt>GLOBL<\/tt><\/span><span>\u00a0makes the symbol global, and the\u00a0<\/span><span><tt>$4<\/tt><\/span><span>\u00a0says how many bytes the symbol occupies. Uninitialized data is zeroed automatically. The character\u00a0<\/span><span><tt>\\z<\/tt><\/span><span>\u00a0is equivalent to the C\u00a0<\/span><span><tt>\\0.<\/tt><\/span><span>\u00a0The string in a\u00a0<\/span><span><tt>DATA<\/tt><\/span><span>\u00a0statement may contain a maximum of eight bytes; build larger strings piecewise. Two pseudo-instructions,\u00a0<\/span><span><tt>DYNT<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>INIT<\/tt><\/span><span>, allow the (obsolete) Alef compilers to build dynamic type information during the load phase. The\u00a0<\/span><span><tt>DYNT<\/tt><\/span><span>\u00a0pseudo-instruction has two forms:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\/1\u5b9a\u4e49\u8981\u5b9a\u4e49\u7684\u5b57\u8282\u6570\uff0cGLOBL\u4f7f\u7b26\u53f7\u6210\u4e3a\u5168\u5c40\u7684\uff0c$4\u8868\u793a\u7b26\u53f7\u5360\u7528\u7684\u5b57\u8282\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u672a\u521d\u59cb\u5316\u7684\u6570\u636e\u5c06\u81ea\u52a8\u5f52\u96f6\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5b57\u7b26\\z\u76f8\u5f53\u4e8eC \\0\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">DATA\u8bed\u53e5\u4e2d\u7684\u5b57\u7b26\u4e32\u6700\u591a\u53ef\u4ee5\u5305\u542b8\u4e2a\u5b57\u8282;<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u5206\u6bb5\u6784\u5efa\u66f4\u5927\u7684\u5b57\u7b26\u4e32\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u4e24\u4e2a\u4f2a\u6307\u4ee4DYNT\u548cINIT\u5141\u8bb8(\u8fc7\u65f6\u7684)Alef\u7f16\u8bd1\u5668\u5728\u52a0\u8f7d\u9636\u6bb5\u6784\u5efa\u52a8\u6001\u7c7b\u578b\u4fe1\u606f\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">DYNT\u4f2a\u6307\u4ee4\u6709\u4e24\u79cd\u5f62\u5f0f:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0DYNT\u00a0\u00a0\u00a0\u00a0,\u00a0ALEF_SI_5+0(SB)<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0DYNT\u00a0\u00a0\u00a0\u00a0ALEF_AS+0(SB),\u00a0ALEF_SI_5+0(SB)<\/tt><\/span><\/p>\n<p><span>In the first form,\u00a0<\/span><span><tt>DYNT<\/tt><\/span><span>\u00a0defines the symbol to be a small unique integer constant, chosen by the loader, which is some multiple of the word size. In the second form,\u00a0<\/span><span><tt>DYNT<\/tt><\/span><span>\u00a0defines the second symbol in the same way, places the address of the most recently defined text symbol in the array specified by the first symbol at the index defined by the value of the second symbol, and then adjusts the size of the array accordingly.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5728\u7b2c\u4e00\u79cd\u5f62\u5f0f\u4e2d\uff0cDYNT\u5c06\u7b26\u53f7\u5b9a\u4e49\u4e3a\u88c5\u5165\u5668\u9009\u62e9\u7684\u4e00\u4e2a\u5c0f\u7684\u60df\u4e00\u6574\u6570\u5e38\u91cf\uff0c\u5b83\u662f\u5355\u8bcd\u5927\u5c0f\u7684\u82e5\u5e72\u500d\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5728\u7b2c\u4e8c\u79cd\u5f62\u5f0f\u4e2d\uff0cDYNT\u4ee5\u540c\u6837\u7684\u65b9\u5f0f\u5b9a\u4e49\u7b2c\u4e8c\u4e2a\u7b26\u53f7\uff0c\u5c06\u7b2c\u4e00\u4e2a\u7b26\u53f7\u6307\u5b9a\u7684\u6570\u7ec4\u4e2d\u6700\u8fd1\u5b9a\u4e49\u7684\u6587\u672c\u7b26\u53f7\u7684\u5730\u5740\u653e\u5728\u7b2c\u4e8c\u4e2a\u7b26\u53f7\u7684\u503c\u5b9a\u4e49\u7684\u7d22\u5f15\u5904\uff0c\u7136\u540e\u76f8\u5e94\u5730\u8c03\u6574\u6570\u7ec4\u7684\u5927\u5c0f\u3002<\/span><\/p>\n<p><span>The\u00a0<\/span><span><tt>INIT<\/tt><\/span><span>\u00a0pseudo-instruction takes the same parameters as a\u00a0<\/span><span><tt>DATA<\/tt><\/span><span>\u00a0statement. Its symbol is used as the base of an array and the data item is installed in the array at the offset specified by the most recent\u00a0<\/span><span><tt>DYNT<\/tt><\/span><span>\u00a0pseudo-instruction. The size of the array is adjusted accordingly. The\u00a0<\/span><span><tt>DYNT<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>INIT<\/tt><\/span><span>\u00a0pseudo-instructions are not implemented on the 68020.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0 highlight\">INIT\u4f2a\u6307\u4ee4\u63a5\u53d7\u4e0eDATA\u8bed\u53e5\u76f8\u540c\u7684\u53c2\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5b83\u7684\u7b26\u53f7\u88ab\u7528\u4f5c\u6570\u7ec4\u7684\u57fa\u6570\uff0c\u6570\u636e\u9879\u88ab\u5b89\u88c5\u5728\u7531\u6700\u65b0\u7684DYNT\u4f2a\u6307\u4ee4\u6307\u5b9a\u7684\u504f\u79fb\u4f4d\u7f6e\u7684\u6570\u7ec4\u4e2d\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u76f8\u5e94\u5730\u8c03\u6574\u6570\u7ec4\u7684\u5927\u5c0f\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">DYNT\u548cINIT\u4f2a\u6307\u4ee4\u6ca1\u6709\u572868020\u4e0a\u5b9e\u73b0\u3002<\/span><\/p>\n<p><span><b>Defining a procedure<\/b><\/span><\/p>\n<p><span>Entry points are defined by the pseudo-operation\u00a0<\/span><span><tt>TEXT<\/tt><\/span><span>, which takes as arguments the name of the procedure (including the ubiquitous\u00a0<\/span><span><tt>(SB)<\/tt><\/span><span>) and the number of bytes of automatic storage to pre-allocate on the stack, which will usually be zero when writing assembly language programs. On machines with a link register, such as the MIPS and SPARC, the special value -4 instructs the loader to generate no PC save and restore instructions, even if the function is not a leaf. Here is a complete procedure that returns the sum of its two arguments:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5165\u53e3\u70b9\u7531\u4f2a\u64cd\u4f5cTEXT\u5b9a\u4e49\uff0c\u8be5\u64cd\u4f5c\u5c06\u8fc7\u7a0b\u7684\u540d\u79f0(\u5305\u62ec\u6cdb\u5728(SB))\u548c\u8981\u9884\u5148\u5206\u914d\u5230\u5806\u6808\u4e0a\u7684\u81ea\u52a8\u5b58\u50a8\u7684\u5b57\u8282\u6570\u4f5c\u4e3a\u53c2\u6570\uff0c\u5728\u7f16\u5199\u6c47\u7f16\u8bed\u8a00\u7a0b\u5e8f\u65f6\uff0c\u5b57\u8282\u6570\u901a\u5e38\u4e3a\u96f6\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5728\u5177\u6709\u94fe\u63a5\u5bc4\u5b58\u5668\u7684\u673a\u5668\u4e0a\uff0c\u5982MIPS\u548cSPARC\uff0c\u7279\u6b8a\u503c-4\u6307\u793a\u52a0\u8f7d\u5668\u4e0d\u751f\u6210PC\u4fdd\u5b58\u548c\u6062\u590d\u6307\u4ee4\uff0c\u5373\u4f7f\u8be5\u51fd\u6570\u4e0d\u662f\u53f6\u51fd\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4e0b\u9762\u662f\u4e00\u4e2a\u8fd4\u56de\u5176\u4e24\u4e2a\u53c2\u6570\u7684\u548c\u7684\u5b8c\u6574\u8fc7\u7a0b:<\/span><\/p>\n<p><span><tt>TEXT\u00a0\u00a0\u00a0\u00a0sum(SB),\u00a0$0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0arg1+0(FP),\u00a0R0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0ADDL\u00a0\u00a0\u00a0\u00a0arg2+4(FP),\u00a0R0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0RTS<\/tt><\/span><\/p>\n<p><span>An optional middle argument to the\u00a0<\/span><span><tt>TEXT<\/tt><\/span><span>\u00a0pseudo-op is a bit field of options to the loader. Setting the 1 bit suspends profiling the function when profiling is enabled for the rest of the program. For example,<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">TEXT\u4f2a\u8fd0\u7b97\u7684\u53ef\u9009\u4e2d\u95f4\u53c2\u6570\u662f\u52a0\u8f7d\u5668\u7684\u9009\u9879\u4f4d\u57df\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5f53\u4e3a\u7a0b\u5e8f\u7684\u5176\u4f59\u90e8\u5206\u542f\u7528\u5206\u6790\u65f6\uff0c\u8bbe\u7f6e1\u4f4d\u5c06\u6682\u505c\u5206\u6790\u51fd\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4f8b\u5982,<\/span><\/p>\n<p><span><tt>TEXT\u00a0\u00a0\u00a0\u00a0sum(SB),\u00a01,\u00a0$0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0arg1+0(FP),\u00a0R0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0ADDL\u00a0\u00a0\u00a0\u00a0arg2+4(FP),\u00a0R0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0RTS<\/tt><\/span><\/p>\n<p><span>will not be profiled; the first version above would be. Subroutines with peculiar state, such as system call routines, should not be profiled.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4e0d\u4f1a\u88ab\u5256\u6790;<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u4e0a\u9762\u7684\u7b2c\u4e00\u4e2a\u7248\u672c\u662f\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5177\u6709\u7279\u6b8a\u72b6\u6001\u7684\u5b50\u4f8b\u7a0b\uff0c\u4f8b\u5982\u7cfb\u7edf\u8c03\u7528\u4f8b\u7a0b\uff0c\u4e0d\u5e94\u8be5\u88ab\u5206\u6790\u3002<\/span><\/p>\n<p><span>Setting the 2 bit allows multiple definitions of the same\u00a0<\/span><span><tt>TEXT<\/tt><\/span><span>\u00a0symbol in a program; the loader will place only one such function in the image. It was emitted only by the Alef compilers.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u8bbe\u7f6e2\u4f4d\u5141\u8bb8\u5728\u7a0b\u5e8f\u4e2d\u5bf9\u540c\u4e00TEXT\u7b26\u53f7\u8fdb\u884c\u591a\u4e2a\u5b9a\u4e49;<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u5c06\u53ea\u5728\u56fe\u50cf\u4e2d\u653e\u7f6e\u4e00\u4e2a\u8fd9\u6837\u7684\u51fd\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5b83\u53ea\u7531Alef\u7f16\u8bd1\u5668\u53d1\u51fa\u3002<\/span><\/p>\n<p><span>Subroutines to be called from C should place their result in\u00a0<\/span><span><tt>R0<\/tt><\/span><span>, even if it is an address. Floating point values are returned in\u00a0<\/span><span><tt>F0<\/tt><\/span><span>. Functions that return a structure to a C program receive as their first argument the address of the location to store the result;\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0is unused in the calling protocol for such procedures. A subroutine is responsible for saving its own registers, and therefore is free to use any registers without saving them (\u2018\u2018caller saves\u2019\u2019).\u00a0<\/span><span><tt>A6<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>A7<\/tt><\/span><span>\u00a0are the exceptions as described above.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4eceC\u8c03\u7528\u7684\u5b50\u4f8b\u7a0b\u5e94\u8be5\u5c06\u7ed3\u679c\u653e\u5728R0\u4e2d\uff0c\u5373\u4f7f\u5b83\u662f\u4e00\u4e2a\u5730\u5740\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6d6e\u70b9\u503c\u5728F0\u4e2d\u8fd4\u56de\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5411C\u7a0b\u5e8f\u8fd4\u56de\u7ed3\u6784\u7684\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u662f\u5b58\u50a8\u7ed3\u679c\u7684\u4f4d\u7f6e\u5730\u5740;<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">R0\u5728\u8fd9\u7c7b\u8fc7\u7a0b\u7684\u8c03\u7528\u534f\u8bae\u4e2d\u6ca1\u6709\u4f7f\u7528\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u5b50\u4f8b\u7a0b\u8d1f\u8d23\u4fdd\u5b58\u5b83\u81ea\u5df1\u7684\u5bc4\u5b58\u5668\uff0c\u56e0\u6b64\u53ef\u4ee5\u81ea\u7531\u4f7f\u7528\u4efb\u4f55\u5bc4\u5b58\u5668\u800c\u4e0d\u4fdd\u5b58\u5b83\u4eec(\u201c\u8c03\u7528\u8005\u4fdd\u5b58\u201d)\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u5982\u524d\u6240\u8ff0\uff0cA6\u548cA7\u662f\u4f8b\u5916\u3002<\/span><\/p>\n<p><span><b>When in doubt<\/b><\/span><\/p>\n<p><span>If you get confused, try using the\u00a0<\/span><span><tt>-S<\/tt><\/span><span>\u00a0option to\u00a0<\/span><span><tt>2c<\/tt><\/span><span>\u00a0and compiling a sample program. The standard output is valid input to the assembler.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5982\u679c\u60a8\u611f\u5230\u56f0\u60d1\uff0c\u8bf7\u5c1d\u8bd5\u5bf92c\u4f7f\u7528-S\u9009\u9879\u5e76\u7f16\u8bd1\u4e00\u4e2a\u793a\u4f8b\u7a0b\u5e8f\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6807\u51c6\u8f93\u51fa\u662f\u6c47\u7f16\u7a0b\u5e8f\u7684\u6709\u6548\u8f93\u5165\u3002<\/span><\/p>\n<p><span><b>Instructions<\/b><\/span><\/p>\n<p><span>The instruction set of the assembler is not identical to that of the machine. It is chosen to match what the compiler generates, augmented slightly by specific needs of the operating system. For example,\u00a0<\/span><span><tt>2a<\/tt><\/span><span>\u00a0does not distinguish between the various forms of\u00a0<\/span><span><tt>MOVE<\/tt><\/span><span>\u00a0instruction: move quick, move address, etc. Instead the context does the job. For example,<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u7684\u6307\u4ee4\u96c6\u4e0e\u673a\u5668\u7684\u6307\u4ee4\u96c6\u4e0d\u76f8\u540c\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5b83\u7684\u9009\u62e9\u662f\u4e3a\u4e86\u5339\u914d\u7f16\u8bd1\u5668\u751f\u6210\u7684\u5185\u5bb9\uff0c\u5e76\u6839\u636e\u64cd\u4f5c\u7cfb\u7edf\u7684\u7279\u5b9a\u9700\u6c42\u7a0d\u5fae\u8fdb\u884c\u4e86\u6269\u5145\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c2a\u4e0d\u533a\u5206\u5404\u79cd\u5f62\u5f0f\u7684MOVE\u6307\u4ee4:MOVE quick, MOVE address\u7b49\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u76f8\u53cd\uff0c\u662f\u73af\u5883\u5728\u8d77\u4f5c\u7528\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u4f8b\u5982,<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0$1,\u00a0R1<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVL\u00a0\u00a0\u00a0\u00a0A0,\u00a0R2<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVW\u00a0\u00a0\u00a0\u00a0SR,\u00a0R3<\/tt><\/span><\/p>\n<p><span>generates official\u00a0<\/span><span><tt>MOVEQ<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVEA<\/tt><\/span><span>, and\u00a0<\/span><span><tt>MOVESR<\/tt><\/span><span>\u00a0instructions. A number of instructions do not have the syntax necessary to specify their entire capabilities. Notable examples are the bitfield instructions, the multiply and divide instructions, etc. For a complete set of generated instruction names (in\u00a0<\/span><span><tt>2a<\/tt><\/span><span>\u00a0notation, not Motorola\u2019s) see the file\u00a0<\/span><span><tt>\/sys\/src\/cmd\/2c\/2.out.h<\/tt><\/span><span>. Despite its name, this file contains an enumeration of the instructions that appear in the intermediate files generated by the compiler, which correspond exactly to lines of assembly language.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0 highlight\">\u751f\u6210\u5b98\u65b9\u7684MOVEQ, MOVEA\u548cMOVESR\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u8bb8\u591a\u6307\u4ee4\u6ca1\u6709\u6307\u5b9a\u5176\u5168\u90e8\u529f\u80fd\u6240\u9700\u7684\u8bed\u6cd5\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u8457\u540d\u7684\u4f8b\u5b50\u662f\u4f4d\u57df\u6307\u4ee4\u3001\u4e58\u6cd5\u548c\u9664\u6cd5\u6307\u4ee4\u7b49\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u8981\u83b7\u5f97\u751f\u6210\u7684\u5b8c\u6574\u6307\u4ee4\u540d\u96c6(\u4ee52a\u8868\u793a\u6cd5\uff0c\u800c\u4e0d\u662fMotorola\u7684\u8868\u793a\u6cd5)\uff0c\u8bf7\u53c2\u9605\u6587\u4ef6\/sys\/src\/cmd\/2c\/2.out.h\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u5c3d\u7ba1\u540d\u4e3a\u6b64\u6587\u4ef6\uff0c\u4f46\u8be5\u6587\u4ef6\u5305\u542b\u7f16\u8bd1\u5668\u751f\u6210\u7684\u4e2d\u95f4\u6587\u4ef6\u4e2d\u51fa\u73b0\u7684\u6307\u4ee4\u679a\u4e3e\uff0c\u8fd9\u4e9b\u6307\u4ee4\u4e0e\u6c47\u7f16\u8bed\u8a00\u7684\u884c\u5b8c\u5168\u5bf9\u5e94\u3002<\/span><\/p>\n<p><span><b>Laying down instructions<\/b><\/span><\/p>\n<p><span>The loader modifies the code produced by the assembler and compiler. It folds branches, copies short sequences of code to eliminate branches, and discards unreachable code. The first instruction of every function is assumed to be reachable. The pseudo-instruction\u00a0<\/span><span><tt>NOP<\/tt><\/span><span>, which you may see in compiler output, means no instruction at all, rather than an instruction that does nothing. The loader discards all\u00a0<\/span><span><tt>NOP<\/tt><\/span><span>\u2019s.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u4fee\u6539\u7531\u6c47\u7f16\u7a0b\u5e8f\u548c\u7f16\u8bd1\u5668\u751f\u6210\u7684\u4ee3\u7801\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5b83\u6298\u53e0\u5206\u652f\uff0c\u590d\u5236\u77ed\u4ee3\u7801\u5e8f\u5217\u4ee5\u6d88\u9664\u5206\u652f\uff0c\u5e76\u4e22\u5f03\u4e0d\u53ef\u8bbf\u95ee\u7684\u4ee3\u7801\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u6bcf\u4e2a\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u6307\u4ee4\u90fd\u5047\u8bbe\u662f\u53ef\u8fbe\u7684\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u60a8\u53ef\u80fd\u5728\u7f16\u8bd1\u5668\u8f93\u51fa\u4e2d\u770b\u5230\u7684\u4f2a\u6307\u4ee4NOP\u610f\u5473\u7740\u6839\u672c\u6ca1\u6709\u6307\u4ee4\uff0c\u800c\u4e0d\u662f\u4ec0\u4e48\u90fd\u4e0d\u505a\u7684\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u4e22\u5f03\u6240\u6709NOP\u3002<\/span><\/p>\n<p><span>To generate a true\u00a0<\/span><span><tt>NOP<\/tt><\/span><span>\u00a0instruction, or any other instruction not known to the assembler, use a\u00a0<\/span><span><tt>WORD<\/tt><\/span><span>\u00a0pseudo-instruction. Such instructions on RISCs are not scheduled by the loader and must have their delay slots filled manually.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u8981\u751f\u6210\u771f\u6b63\u7684NOP\u6307\u4ee4\uff0c\u6216\u6c47\u7f16\u7a0b\u5e8f\u4e0d\u77e5\u9053\u7684\u4efb\u4f55\u5176\u4ed6\u6307\u4ee4\uff0c\u8bf7\u4f7f\u7528WORD\u4f2a\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">risc\u4e0a\u7684\u8fd9\u4e9b\u6307\u4ee4\u4e0d\u662f\u7531\u52a0\u8f7d\u5668\u8c03\u5ea6\u7684\uff0c\u5fc5\u987b\u624b\u52a8\u586b\u5145\u5b83\u4eec\u7684\u5ef6\u8fdf\u69fd\u3002<\/span><\/p>\n<p><span><b>MIPS<\/b><\/span><\/p>\n<p><span>The registers are only addressed by number:\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>R31<\/tt><\/span><span>.\u00a0<\/span><span><tt>R29<\/tt><\/span><span>\u00a0is the stack pointer;\u00a0<\/span><span><tt>R30<\/tt><\/span><span>\u00a0is used as the static base pointer, the analogue of\u00a0<\/span><span><tt>A6<\/tt><\/span><span>\u00a0on the 68020. Its value is the address of the global symbol\u00a0<\/span><span><tt>setR30(SB)<\/tt><\/span><span>. The register holding returned values from subroutines is\u00a0<\/span><span><tt>R1<\/tt><\/span><span>. When a function is called, space for the first argument is reserved at\u00a0<\/span><span><tt>0(FP)<\/tt><\/span><span>\u00a0but in C (not Alef) the value is passed in\u00a0<\/span><span><tt>R1<\/tt><\/span><span>\u00a0instead.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u53ea\u901a\u8fc7\u6570\u5b57\u5bfb\u5740:R0\u5230R31\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">R29\u662f\u5806\u6808\u6307\u9488;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">R30\u88ab\u7528\u4f5c\u9759\u6001\u57fa\u51c6\u6307\u9488\uff0c\u7c7b\u4f3c\u4e8e68020\u4e0a\u7684A6\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u5b83\u7684\u503c\u662f\u5168\u5c40\u7b26\u53f7setR30(SB)\u7684\u5730\u5740\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u4fdd\u5b58\u5b50\u4f8b\u7a0b\u8fd4\u56de\u503c\u7684\u5bc4\u5b58\u5668\u662fR1\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u5f53\u51fd\u6570\u88ab\u8c03\u7528\u65f6\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u7684\u7a7a\u95f4\u88ab\u4fdd\u7559\u57280(FP)\uff0c\u4f46\u5728C(\u4e0d\u662fAlef)\u4e2d\uff0c\u8be5\u503c\u88ab\u4f20\u9012\u5230R1\u4e2d\u3002<\/span><\/p>\n<p><span>The loader uses\u00a0<\/span><span><tt>R28<\/tt><\/span><span>\u00a0as a temporary. The system uses\u00a0<\/span><span><tt>R26<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>R27<\/tt><\/span><span>\u00a0as interrupt-time temporaries. Therefore none of these registers should be used in user code.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u4f7f\u7528R28\u4f5c\u4e3a\u4e34\u65f6\u5bf9\u8c61\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u7cfb\u7edf\u4f7f\u7528R26\u548cR27\u4f5c\u4e3a\u4e2d\u65ad\u65f6\u95f4\u4e34\u65f6\u53d8\u91cf\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u56e0\u6b64\uff0c\u5728\u7528\u6237\u4ee3\u7801\u4e2d\u4e0d\u5e94\u8be5\u4f7f\u7528\u8fd9\u4e9b\u5bc4\u5b58\u5668\u3002<\/span><\/p>\n<p><span>The control registers are not known to the assembler. Instead they are numbered registers\u00a0<\/span><span><tt>M0<\/tt><\/span><span>,\u00a0<\/span><span><tt>M1<\/tt><\/span><span>, etc. Use this trick to access, say,\u00a0<\/span><span><tt>STATUS<\/tt><\/span><span>:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0 highlight\">\u6c47\u7f16\u7a0b\u5e8f\u4e0d\u77e5\u9053\u63a7\u5236\u5bc4\u5b58\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u53d6\u800c\u4ee3\u4e4b\u7684\u662f\u7f16\u53f7\u4e3aM0\u3001M1\u7b49\u7684\u5bc4\u5b58\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4f7f\u7528\u8fd9\u4e2a\u6280\u5de7\u6765\u8bbf\u95ee\uff0c\u6bd4\u5982\u8bf4\uff0cSTATUS:<\/span><\/p>\n<p><span><tt>#define\u00a0STATUS\u00a0\u00a012<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVW\u00a0\u00a0\u00a0\u00a0M(STATUS),\u00a0R1<\/tt><\/span><\/p>\n<p><span>Floating point registers are called\u00a0<\/span><span><tt>F0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>F31<\/tt><\/span><span>. By convention,\u00a0<\/span><span><tt>F24<\/tt><\/span><span>\u00a0must be initialized to the value 0.0,\u00a0<\/span><span><tt>F26<\/tt><\/span><span>\u00a0to 0.5,\u00a0<\/span><span><tt>F28<\/tt><\/span><span>\u00a0to 1.0, and\u00a0<\/span><span><tt>F30<\/tt><\/span><span>\u00a0to 2.0; this is done by the operating system.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6d6e\u70b9\u5bc4\u5b58\u5668\u79f0\u4e3aF0\u5230F31\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6309\u7167\u7ea6\u5b9a\uff0cF24\u5fc5\u987b\u521d\u59cb\u5316\u4e3a\u503c0.0,F26\u521d\u59cb\u5316\u4e3a0.5,F28\u521d\u59cb\u5316\u4e3a1.0,F30\u521d\u59cb\u5316\u4e3a2.0;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u8fd9\u662f\u7531\u64cd\u4f5c\u7cfb\u7edf\u5b8c\u6210\u7684\u3002<\/span><\/p>\n<p><span>The instructions and their syntax are different from those of the manufacturer\u2019s manual. There are no\u00a0<\/span><span><tt>lui<\/tt><\/span><span>\u00a0and kin; instead there are\u00a0<\/span><span><tt>MOVW<\/tt><\/span><span>\u00a0(move word),\u00a0<\/span><span><tt>MOVH<\/tt><\/span><span>\u00a0(move halfword), and\u00a0<\/span><span><tt>MOVB<\/tt><\/span><span>\u00a0(move byte) pseudo-instructions. If the operand is unsigned, the instructions are\u00a0<\/span><span><tt>MOVHU<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>MOVBU<\/tt><\/span><span>. The order of operands is from left to right in dataflow order, just as on the 68020 but not as in MIPS documentation. This means that the\u00a0<\/span><span><tt>Bcond<\/tt><\/span><span>\u00a0instructions are reversed with respect to the book; for example, a\u00a0<\/span><span><tt>va<\/tt><\/span><span>\u00a0<\/span><span><tt>BGTZ<\/tt><\/span><span>\u00a0generates a MIPS\u00a0<\/span><span><tt>bltz<\/tt><\/span><span>\u00a0instruction.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u8bf4\u660e\u4e66\u53ca\u5176\u8bed\u6cd5\u4e0e\u5236\u9020\u5546\u624b\u518c\u4e2d\u7684\u4e0d\u540c\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6ca1\u6709lui\u548ckin;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u53d6\u800c\u4ee3\u4e4b\u7684\u662fMOVW(\u79fb\u52a8\u5b57)\u3001MOVH(\u79fb\u52a8\u534a\u5b57)\u548cMOVB(\u79fb\u52a8\u5b57\u8282)\u4f2a\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u5982\u679c\u64cd\u4f5c\u6570\u662f\u65e0\u7b26\u53f7\u7684\uff0c\u5219\u6307\u4ee4\u662fMOVHU\u548cMOVBU\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u64cd\u4f5c\u6570\u7684\u987a\u5e8f\u5728\u6570\u636e\u6d41\u987a\u5e8f\u4e2d\u4ece\u5de6\u5230\u53f3\uff0c\u4e0e68020\u4e0a\u76f8\u540c\uff0c\u4f46\u4e0eMIPS\u6587\u6863\u4e0d\u540c\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u8fd9\u610f\u5473\u7740Bcond\u6307\u4ee4\u4e0e\u4e66\u76f8\u53cd;<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c\u4e00\u4e2ava BGTZ\u751f\u6210\u4e00\u4e2aMIPS bltz\u6307\u4ee4\u3002<\/span><\/p>\n<p><span>The assembler is for the R2000, R3000, and most of the R4000 and R6000 architectures. It understands the 64-bit instructions <\/span><span><tt>MOVV<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVVL<\/tt><\/span><span>,\u00a0<\/span><span><tt>ADDV<\/tt><\/span><span>,\u00a0<\/span><span><tt>ADDVU<\/tt><\/span><span>,\u00a0<\/span><span><tt>SUBV<\/tt><\/span><span>,\u00a0<\/span><span><tt>SUBVU<\/tt><\/span><span>,\u00a0<\/span><span><tt>MULV<\/tt><\/span><span>,\u00a0<\/span><span><tt>MULVU<\/tt><\/span><span>,\u00a0<\/span><span><tt>DIVV<\/tt><\/span><span>,\u00a0<\/span><span><tt>DIVVU<\/tt><\/span><span>,\u00a0<\/span><span><tt>SLLV<\/tt><\/span><span>,\u00a0<\/span><span><tt>SRLV<\/tt><\/span><span>, and\u00a0<\/span><span><tt>SRAV<\/tt><\/span><span>. The assembler does not have any cache, load-linked, or store-conditional instructions.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u8be5\u6c47\u7f16\u7a0b\u5e8f\u9002\u7528\u4e8eR2000\u3001R3000\u4ee5\u53ca\u5927\u591a\u6570R4000\u548cR6000\u4f53\u7cfb\u7ed3\u6784\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5b83\u7406\u89e364\u4f4d\u6307\u4ee4MOVV, MOVVL, ADDV, ADDVU, SUBV, SUBVU, MULV, MULVU, DIVV, DIVVU, SLLV, SRLV\u548cSRAV\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u6ca1\u6709\u4efb\u4f55\u7f13\u5b58\u3001\u52a0\u8f7d\u94fe\u63a5\u6216\u5b58\u50a8\u6761\u4ef6\u6307\u4ee4\u3002<\/span><\/p>\n<p><span>Some assembler instructions are expanded into multiple instructions by the loader. For example the loader may convert the load of a 32 bit constant into an\u00a0<\/span><span><tt>lui<\/tt><\/span><span>\u00a0followed by an\u00a0<\/span><span><tt>ori<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0 highlight\">\u4e00\u4e9b\u6c47\u7f16\u7a0b\u5e8f\u6307\u4ee4\u88ab\u52a0\u8f7d\u5668\u6269\u5c55\u4e3a\u591a\u4e2a\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c\u52a0\u8f7d\u5668\u53ef\u4ee5\u5c06\u4e00\u4e2a32\u4f4d\u5e38\u91cf\u7684\u52a0\u8f7d\u8f6c\u6362\u4e3a\u4e00\u4e2alui\u540e\u8ddf\u4e00\u4e2aori\u3002<\/span><\/p>\n<p><span>Assembler instructions should be laid out as if there were no load, branch, or floating point compare delay slots; the loader will rearrange\u2014<\/span><span><i>schedule<\/i><\/span><span>\u2014the instructions to guarantee correctness and improve performance. The only exception is that the correct scheduling of instructions that use control registers varies from model to model of machine (and is often undocumented) so you should schedule such instructions by hand to guarantee correct behavior. The loader generates<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u6307\u4ee4\u7684\u5e03\u5c40\u5e94\u8be5\u50cf\u6ca1\u6709\u8d1f\u8f7d\u3001\u5206\u652f\u6216\u6d6e\u70b9\u6bd4\u8f83\u5ef6\u8fdf\u69fd\u4e00\u6837;<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u5c06\u91cd\u65b0\u5b89\u6392-\u8c03\u5ea6-\u6307\u4ee4\uff0c\u4ee5\u786e\u4fdd\u6b63\u786e\u6027\u548c\u63d0\u9ad8\u6027\u80fd\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u552f\u4e00\u7684\u4f8b\u5916\u662f\uff0c\u4f7f\u7528\u63a7\u5236\u5bc4\u5b58\u5668\u7684\u6307\u4ee4\u7684\u6b63\u786e\u8c03\u5ea6\u56e0\u673a\u5668\u7684\u4e0d\u540c\u6a21\u578b\u800c\u4e0d\u540c(\u800c\u4e14\u901a\u5e38\u6ca1\u6709\u6587\u6863\u8bb0\u5f55)\uff0c\u56e0\u6b64\u60a8\u5e94\u8be5\u624b\u52a8\u8c03\u5ea6\u6b64\u7c7b\u6307\u4ee4\u4ee5\u786e\u4fdd\u6b63\u786e\u7684\u884c\u4e3a\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u52a0\u8f7d\u5668\u751f\u6210<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0NOR\u00a0R0,\u00a0R0,\u00a0R0<\/tt><\/span><\/p>\n<p><span>when it needs a true no-op instruction. Use exactly this instruction when scheduling code manually; the loader recognizes it and schedules the code before it and after it independently. Also,\u00a0<\/span><span><tt>WORD<\/tt><\/span><span>\u00a0pseudo-ops are scheduled like no-ops.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5f53\u5b83\u9700\u8981\u4e00\u4e2a\u771f\u6b63\u7684\u65e0\u64cd\u4f5c\u6307\u4ee4\u65f6\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5728\u624b\u52a8\u8c03\u5ea6\u4ee3\u7801\u65f6\u5b8c\u5168\u4f7f\u7528\u6b64\u6307\u4ee4;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0 highlight\">\u52a0\u8f7d\u5668\u8bc6\u522b\u5b83\uff0c\u5e76\u5728\u5b83\u4e4b\u524d\u548c\u4e4b\u540e\u5206\u522b\u8c03\u5ea6\u4ee3\u7801\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u53e6\u5916\uff0cWORD\u4f2a\u64cd\u4f5c\u88ab\u5b89\u6392\u4e3a\u65e0\u64cd\u4f5c\u3002<\/span><\/p>\n<p><span>The\u00a0<\/span><span><tt>NOSCHED<\/tt><\/span><span>\u00a0pseudo-op disables instruction scheduling (scheduling is enabled by default);\u00a0<\/span><span><tt>SCHED<\/tt><\/span><span>\u00a0re-enables it. Branch folding, code copying, and dead code elimination are disabled for instructions that are not scheduled.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">NOSCHED\u4f2a\u8fd0\u7b97\u7981\u6b62\u6307\u4ee4\u8c03\u5ea6(\u8c03\u5ea6\u5728\u9ed8\u8ba4\u60c5\u51b5\u4e0b\u662f\u542f\u7528\u7684);<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">SCHED\u91cd\u65b0\u542f\u7528\u5b83\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5bf9\u4e8e\u672a\u8ba1\u5212\u7684\u6307\u4ee4\uff0c\u5c06\u7981\u7528\u5206\u652f\u6298\u53e0\u3001\u4ee3\u7801\u590d\u5236\u548c\u6b7b\u4ee3\u7801\u6d88\u9664\u3002<\/span><\/p>\n<p><span><b>SPARC<\/b><\/span><\/p>\n<p><span>Once you understand the Plan 9 model for the MIPS, the SPARC is familiar. Registers have numerical names only:\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>R31<\/tt><\/span><span>. Forget about register windows: Plan 9 doesn\u2019t use them at all. The machine has 32 global registers, period.\u00a0<\/span><span><tt>R1<\/tt><\/span><span>\u00a0[sic] is the stack pointer.\u00a0<\/span><span><tt>R2<\/tt><\/span><span>\u00a0is the static base register, with value the address of\u00a0<\/span><span><tt>setSB(SB)<\/tt><\/span><span>.\u00a0<\/span><span><tt>R7<\/tt><\/span><span>\u00a0is the return register and also the register holding the first argument to a C (not Alef) function, again with space reserved at\u00a0<\/span><span><tt>0(FP)<\/tt><\/span><span>.\u00a0<\/span><span><tt>R14<\/tt><\/span><span>\u00a0is the loader temporary.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4e00\u65e6\u60a8\u7406\u89e3\u4e86MIPS\u7684Plan 9\u6a21\u578b\uff0c\u5c31\u719f\u6089\u4e86SPARC\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u53ea\u6709\u6570\u5b57\u540d\u79f0:R0\u5230R31\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5fd8\u8bb0\u5bc4\u5b58\u5668\u7a97\u53e3\u5427:plan 9\u6839\u672c\u4e0d\u4f7f\u7528\u5b83\u4eec\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u8fd9\u53f0\u673a\u5668\u670932\u4e2a\u5168\u5c40\u5bc4\u5b58\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">R1 [sic]\u662f\u5806\u6808\u6307\u9488\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">R2\u662f\u9759\u6001\u57fa\u5bc4\u5b58\u5668\uff0c\u503c\u4e3asetSB(SB)\u7684\u5730\u5740\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">R7\u662f\u8fd4\u56de\u5bc4\u5b58\u5668\uff0c\u4e5f\u662f\u4fdd\u5b58C(\u4e0d\u662fAlef)\u51fd\u6570\u7684\u7b2c\u4e00\u4e2a\u53c2\u6570\u7684\u5bc4\u5b58\u5668\uff0c\u540c\u6837\u4fdd\u7559\u7a7a\u95f4\u4e3a0(FP)\u3002<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">R14\u662f\u4e34\u65f6\u52a0\u8f7d\u5668\u3002<\/span><\/p>\n<p><span>Floating-point registers are exactly as on the MIPS.<\/span><\/p>\n<p><span>\u6d6e\u70b9\u5bc4\u5b58\u5668\u4e0eMIPS\u4e0a\u7684\u5bc4\u5b58\u5668\u5b8c\u5168\u76f8\u540c\u3002<\/span><\/p>\n<p><span>The control registers are known by names such as\u00a0<\/span><span><tt>FSR<\/tt><\/span><span>. The instructions to access these registers are\u00a0<\/span><span><tt>MOVW<\/tt><\/span><span>\u00a0instructions, for example<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u63a7\u5236\u5bc4\u5b58\u5668\u6709\u8bf8\u5982FSR\u4e4b\u7c7b\u7684\u540d\u79f0\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c\u8bbf\u95ee\u8fd9\u4e9b\u5bc4\u5b58\u5668\u7684\u6307\u4ee4\u662fMOVW\u6307\u4ee4<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVW\u00a0\u00a0\u00a0\u00a0Y,\u00a0R8<\/tt><\/span><\/p>\n<p><span>for the SPARC instruction<\/span><\/p>\n<p><span>\u7684SPARC\u6307\u4ee4<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0rdy\u00a0%r8<\/tt><\/span><\/p>\n<p><span>Move instructions are similar to those on the MIPS: pseudo-operations that turn into appropriate sequences of\u00a0<\/span><span><tt>sethi<\/tt><\/span><span>\u00a0instructions, adds, etc. Instructions read from left to right. Because the arguments are flipped to\u00a0<\/span><span><tt>SUBCC<\/tt><\/span><span>, the condition codes are not inverted as on the MIPS.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">Move\u6307\u4ee4\u7c7b\u4f3c\u4e8eMIPS\u4e0a\u7684\u6307\u4ee4:\u8f6c\u6362\u4e3a\u9002\u5f53\u5e8f\u5217\u7684sethi\u6307\u4ee4\u3001\u6dfb\u52a0\u6307\u4ee4\u7b49\u7684\u4f2a\u64cd\u4f5c\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u8bf4\u660e\u4ece\u5de6\u5230\u53f3\u8bfb\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u56e0\u4e3a\u53c2\u6570\u88ab\u7ffb\u8f6c\u5230SUBCC\uff0c\u6240\u4ee5\u6761\u4ef6\u4ee3\u7801\u4e0d\u50cf\u5728MIPS\u4e0a\u90a3\u6837\u88ab\u98a0\u5012\u3002<\/span><\/p>\n<p><span>The syntax for the ASI stuff is, for example to move a word from ASI 2:<\/span><\/p>\n<p><span>ASI\u7684\u8bed\u6cd5\u662f\u8fd9\u6837\u7684\uff0c\u4f8b\u5982\u4eceASI 2\u4e2d\u79fb\u52a8\u4e00\u4e2a\u5355\u8bcd:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVW\u00a0\u00a0\u00a0\u00a0(R7,\u00a02),\u00a0R8<\/tt><\/span><\/p>\n<p><span>The syntax for double indexing is<\/span><\/p>\n<p><span>\u53cc\u7d22\u5f15\u7684\u8bed\u6cd5\u662f<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVW\u00a0\u00a0\u00a0\u00a0(R7+R8),\u00a0R9<\/tt><\/span><\/p>\n<p><span>The SPARC\u2019s instruction scheduling is similar to the MIPS\u2019s. The official no-op instruction is:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">SPARC\u7684\u6307\u4ee4\u8c03\u5ea6\u4e0eMIPS\u7684\u7c7b\u4f3c\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5b98\u65b9\u7684\u65e0\u64cd\u4f5c\u8bf4\u660e\u662f:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0ORN\u00a0R0,\u00a0R0,\u00a0R0<\/tt><\/span><\/p>\n<p><span><b>i960<\/b><\/span><\/p>\n<p><span>Registers are numbered\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>R31<\/tt><\/span><span>. Stack pointer is\u00a0<\/span><span><tt>R29<\/tt><\/span><span>; return register is\u00a0<\/span><span><tt>R4<\/tt><\/span><span>; static base is\u00a0<\/span><span><tt>R28<\/tt><\/span><span>; it is initialized to the address of\u00a0<\/span><span><tt>setSB(SB)<\/tt><\/span><span>.\u00a0<\/span><span><tt>R3<\/tt><\/span><span>\u00a0must be zero; this should be done manually early in execution by<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u7f16\u53f7\u4e3aR0\u5230R31\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5806\u6808\u6307\u9488\u4e3aR29;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u8fd4\u56de\u5bc4\u5b58\u5668\u4e3aR4;<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u9759\u6001\u5e95\u5ea7\u4e3aR28;<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u5b83\u88ab\u521d\u59cb\u5316\u4e3asetSB(SB)\u7684\u5730\u5740\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">R3\u5fc5\u987b\u662f\u96f6;<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u8fd9\u5e94\u8be5\u5728\u6267\u884c\u7684\u65e9\u671f\u624b\u52a8\u5b8c\u6210<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0SUBO\u00a0\u00a0\u00a0\u00a0R3,\u00a0R3<\/tt><\/span><\/p>\n<p><span><\/span><span><tt>R27<\/tt><\/span><span>\u00a0is the loader temporary.<\/span><\/p>\n<p><span>R27\u662f\u4e34\u65f6\u52a0\u8f7d\u5668\u3002<\/span><\/p>\n<p><span>There is no support for floating point.<\/span><\/p>\n<p><span>\u4e0d\u652f\u6301\u6d6e\u70b9\u6570\u3002<\/span><\/p>\n<p><span>The Intel calling convention is not supported and cannot be used; use\u00a0<\/span><span><tt>BAL<\/tt><\/span><span>\u00a0instead. Instructions are mostly as in the book. The major change is that\u00a0<\/span><span><tt>LOAD<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>STORE<\/tt><\/span><span>\u00a0are both called\u00a0<\/span><span><tt>MOV<\/tt><\/span><span>. The extension character for\u00a0<\/span><span><tt>MOV<\/tt><\/span><span>\u00a0is as in the manual:\u00a0<\/span><span><tt>O<\/tt><\/span><span>\u00a0for ordinal,\u00a0<\/span><span><tt>W<\/tt><\/span><span>\u00a0for signed, etc.<\/span><\/p>\n<p><span data-section=\"4\" data-sentence=\"0\" data-group=\"4-0\" class=\"tgt color_text_0\">\u4e0d\u652f\u6301Intel\u8c03\u7528\u7ea6\u5b9a\uff0c\u4e0d\u80fd\u4f7f\u7528;<\/span><span data-section=\"4\" data-sentence=\"1\" data-group=\"4-1\" class=\"tgt color_text_0\">\u4f7f\u7528BAL\u4ee3\u66ff\u3002<\/span><span data-section=\"4\" data-sentence=\"2\" data-group=\"4-2\" class=\"tgt color_text_0\">\u8bf4\u660e\u4e66\u548c\u4e66\u4e0a\u7684\u5185\u5bb9\u5dee\u4e0d\u591a\u3002<\/span><span data-section=\"4\" data-sentence=\"3\" data-group=\"4-3\" class=\"tgt color_text_0\">\u4e3b\u8981\u7684\u53d8\u5316\u662fLOAD\u548cSTORE\u90fd\u79f0\u4e3aMOV\u3002<\/span><span data-section=\"4\" data-sentence=\"4\" data-group=\"4-4\" class=\"tgt color_text_0\">MOV\u7684\u6269\u5c55\u5b57\u7b26\u4e0e\u624b\u518c\u4e2d\u4e00\u6837:O\u8868\u793a\u5e8f\u6570\uff0cW\u8868\u793a\u6709\u7b26\u53f7\uff0c\u7b49\u7b49\u3002<\/span><\/p>\n<p><span><b>i386<\/b><\/span><\/p>\n<p><span>The assembler assumes 32-bit protected mode. The register names are\u00a0<\/span><span><tt>SP<\/tt><\/span><span>,\u00a0<\/span><span><tt>AX<\/tt><\/span><span>,\u00a0<\/span><span><tt>BX<\/tt><\/span><span>,\u00a0<\/span><span><tt>CX<\/tt><\/span><span>,\u00a0<\/span><span><tt>DX<\/tt><\/span><span>,\u00a0<\/span><span><tt>BP<\/tt><\/span><span>,\u00a0<\/span><span><tt>DI<\/tt><\/span><span>, and\u00a0<\/span><span><tt>SI<\/tt><\/span><span>. The stack pointer (not a pseudo-register) is\u00a0<\/span><span><tt>SP<\/tt><\/span><span>\u00a0and the return register is\u00a0<\/span><span><tt>AX<\/tt><\/span><span>. There is no physical frame pointer but, as for the MIPS,\u00a0<\/span><span><tt>FP<\/tt><\/span><span>\u00a0is a pseudo-register that acts as a frame pointer.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u91c7\u752832\u4f4d\u4fdd\u62a4\u6a21\u5f0f\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u540d\u79f0\u4e3aSP\u3001AX\u3001BX\u3001CX\u3001DX\u3001BP\u3001DI\u548cSI\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u5806\u6808\u6307\u9488(\u4e0d\u662f\u4f2a\u5bc4\u5b58\u5668)\u662fSP\uff0c\u8fd4\u56de\u5bc4\u5b58\u5668\u662fAX\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u6ca1\u6709\u7269\u7406\u5e27\u6307\u9488\uff0c\u4f46\u662f\u5bf9\u4e8eMIPS\u6765\u8bf4\uff0cFP\u662f\u4e00\u4e2a\u5145\u5f53\u5e27\u6307\u9488\u7684\u4f2a\u5bc4\u5b58\u5668\u3002<\/span><\/p>\n<p><span>Opcode names are mostly the same as those listed in the Intel manual with an\u00a0<\/span><span><tt>L<\/tt><\/span><span>,\u00a0<\/span><span><tt>W<\/tt><\/span><span>, or\u00a0<\/span><span><tt>B<\/tt><\/span><span>\u00a0appended to identify 32-bit, 16-bit, and 8-bit operations. The exceptions are loads, stores, and conditionals. All load and store opcodes to and from general registers, special registers (such as\u00a0<\/span><span><tt>CR0,<\/tt><\/span><span>\u00a0<\/span><span><tt>CR3,<\/tt><\/span><span>\u00a0<\/span><span><tt>GDTR,<\/tt><\/span><span>\u00a0<\/span><span><tt>IDTR,<\/tt><\/span><span>\u00a0<\/span><span><tt>SS,<\/tt><\/span><span>\u00a0<\/span><span><tt>CS,<\/tt><\/span><span>\u00a0<\/span><span><tt>DS,<\/tt><\/span><span>\u00a0<\/span><span><tt>ES,<\/tt><\/span><span>\u00a0<\/span><span><tt>FS,<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>GS<\/tt><\/span><span>) or memory are written as<\/span><\/p>\n<p><span data-section=\"2\" data-sentence=\"0\" data-group=\"2-0\" class=\"tgt color_text_0\">\u64cd\u4f5c\u7801\u540d\u79f0\u5927\u591a\u4e0e\u82f1\u7279\u5c14\u624b\u518c\u4e2d\u5217\u51fa\u7684\u64cd\u4f5c\u7801\u540d\u79f0\u76f8\u540c\uff0c\u53ea\u662f\u9644\u52a0\u4e86L\u3001W\u6216B\u6765\u6807\u8bc632\u4f4d\u300116\u4f4d\u548c8\u4f4d\u64cd\u4f5c\u3002<\/span><span data-section=\"2\" data-sentence=\"1\" data-group=\"2-1\" class=\"tgt color_text_0\">\u4f8b\u5916\u662f\u52a0\u8f7d\u3001\u5b58\u50a8\u548c\u6761\u4ef6\u3002<\/span><span data-section=\"2\" data-sentence=\"2\" data-group=\"2-2\" class=\"tgt color_text_0\">\u6240\u6709\u5411\u901a\u7528\u5bc4\u5b58\u5668\u3001\u7279\u6b8a\u5bc4\u5b58\u5668(\u5982CR0\u3001CR3\u3001GDTR\u3001IDTR\u3001SS\u3001CS\u3001DS\u3001ES\u3001FS\u548cGS)\u6216\u5185\u5b58\u7684\u52a0\u8f7d\u548c\u5b58\u50a8\u64cd\u4f5c\u7801\u90fd\u5199\u4e3a<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOV<\/tt><\/span><span><i>x<\/i><\/span><span><tt>\u00a0\u00a0\u00a0\u00a0src,dst<\/tt><\/span><\/p>\n<p><span>where\u00a0<\/span><span><i>x<\/i><\/span><span>\u00a0is\u00a0<\/span><span><tt>L<\/tt><\/span><span>,\u00a0<\/span><span><tt>W<\/tt><\/span><span>, or\u00a0<\/span><span><tt>B<\/tt><\/span><span>. Thus to get\u00a0<\/span><span><tt>AL<\/tt><\/span><span>\u00a0use a\u00a0<\/span><span><tt>MOVB<\/tt><\/span><span>\u00a0instruction. If you need to access\u00a0<\/span><span><tt>AH<\/tt><\/span><span>, you must mention it explicitly in a\u00a0<\/span><span><tt>MOVB<\/tt><\/span><span>:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5176\u4e2dx\u662fL, W\u6216b\uff0c\u56e0\u6b64\u8981\u83b7\u5f97AL\u4f7f\u7528MOVB\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5982\u679c\u4f60\u9700\u8981\u8bbf\u95eeAH\uff0c\u4f60\u5fc5\u987b\u5728MOVB\u4e2d\u663e\u5f0f\u5730\u63d0\u5230\u5b83:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVB\u00a0\u00a0\u00a0\u00a0AH,\u00a0BX<\/tt><\/span><\/p>\n<p><span>There are many examples of illegal moves, for example,<\/span><\/p>\n<p><span>\u975e\u6cd5\u79fb\u52a8\u7684\u4f8b\u5b50\u6709\u5f88\u591a\uff0c\u4f8b\u5982\uff0c<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVB\u00a0\u00a0\u00a0\u00a0BP,\u00a0DI<\/tt><\/span><\/p>\n<p><span>that the loader actually implements as pseudo-operations.<\/span><\/p>\n<p><span>\u52a0\u8f7d\u5668\u5b9e\u9645\u5b9e\u73b0\u4e3a\u4f2a\u64cd\u4f5c\u3002<\/span><\/p>\n<p><span>The names of conditions in all conditional instructions (<\/span><span><tt>J<\/tt><\/span><span>,\u00a0<\/span><span><tt>SET<\/tt><\/span><span>) follow the conventions of the 68020 instead of those of the Intel assembler:\u00a0<\/span><span><tt>JOS<\/tt><\/span><span>,\u00a0<\/span><span><tt>JOC<\/tt><\/span><span>,\u00a0<\/span><span><tt>JCS<\/tt><\/span><span>,\u00a0<\/span><span><tt>JCC<\/tt><\/span><span>,\u00a0<\/span><span><tt>JEQ<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNE<\/tt><\/span><span>,\u00a0<\/span><span><tt>JLS<\/tt><\/span><span>,\u00a0<\/span><span><tt>JHI<\/tt><\/span><span>,\u00a0<\/span><span><tt>JMI<\/tt><\/span><span>,\u00a0<\/span><span><tt>JPL<\/tt><\/span><span>,\u00a0<\/span><span><tt>JPS<\/tt><\/span><span>,\u00a0<\/span><span><tt>JPC<\/tt><\/span><span>,\u00a0<\/span><span><tt>JLT<\/tt><\/span><span>,\u00a0<\/span><span><tt>JGE<\/tt><\/span><span>,\u00a0<\/span><span><tt>JLE<\/tt><\/span><span>, and\u00a0<\/span><span><tt>JGT<\/tt><\/span><span>\u00a0instead of\u00a0<\/span><span><tt>JO<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNO<\/tt><\/span><span>,\u00a0<\/span><span><tt>JB<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNB<\/tt><\/span><span>,\u00a0<\/span><span><tt>JZ<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNZ<\/tt><\/span><span>,\u00a0<\/span><span><tt>JBE<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNBE<\/tt><\/span><span>,\u00a0<\/span><span><tt>JS<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNS<\/tt><\/span><span>,\u00a0<\/span><span><tt>JP<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNP<\/tt><\/span><span>,\u00a0<\/span><span><tt>JL<\/tt><\/span><span>,\u00a0<\/span><span><tt>JNL<\/tt><\/span><span>,\u00a0<\/span><span><tt>JLE<\/tt><\/span><span>, and\u00a0<\/span><span><tt>JNLE<\/tt><\/span><span>.<\/span><\/p>\n<p><span>\u6240\u6709\u6761\u4ef6\u6307\u4ee4(J, SET)\u4e2d\u7684\u6761\u4ef6\u540d\u79f0\u90fd\u9075\u5faa68020\u7684\u7ea6\u5b9a\uff0c\u800c\u4e0d\u662f\u82f1\u7279\u5c14\u6c47\u7f16\u7a0b\u5e8f\u7684\u7ea6\u5b9a:JOS, JOC, JCS, JCC, JEQ, JNE, JLS, JHI, JMI, JPL, JPS, JPC, JLT, JGE, JLE, JGT\uff0c\u800c\u4e0d\u662fJO, JNO, JB, JNB, JZ, JNZ, JBE, JNBE, JS, JNS, JP, JNP, JL, JNL, JLE\uff0c\u548cJNLE\u3002<\/span><\/p>\n<p><span>The addressing modes have syntax like\u00a0<\/span><span><tt>AX<\/tt><\/span><span>,\u00a0<\/span><span><tt>(AX)<\/tt><\/span><span>,\u00a0<\/span><span><tt>(AX)(BX*4)<\/tt><\/span><span>,\u00a0<\/span><span><tt>10(AX)<\/tt><\/span><span>, and\u00a0<\/span><span><tt>10(AX)(BX*4)<\/tt><\/span><span>. The offsets from\u00a0<\/span><span><tt>AX<\/tt><\/span><span>\u00a0can be replaced by offsets from\u00a0<\/span><span><tt>FP<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>SB<\/tt><\/span><span>\u00a0to access names, for example\u00a0<\/span><span><tt>extern+5(SB)(AX*2)<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"4\" data-sentence=\"0\" data-group=\"4-0\" class=\"tgt color_text_0\">\u5bfb\u5740\u6a21\u5f0f\u7684\u8bed\u6cd5\u7c7b\u4f3c\u4e8eAX\u3001(AX)\u3001(AX)(BX*4)\u300110(AX)\u548c10(AX)(BX*4)\u3002<\/span><span data-section=\"4\" data-sentence=\"1\" data-group=\"4-1\" class=\"tgt color_text_0\">\u6765\u81eaAX\u7684\u504f\u79fb\u91cf\u53ef\u4ee5\u88ab\u6765\u81eaFP\u6216SB\u7684\u8bbf\u95ee\u540d\u79f0\u7684\u504f\u79fb\u91cf\u66ff\u6362\uff0c\u4f8b\u5982extern+5(SB)(AX*2)\u3002<\/span><\/p>\n<p><span>Other notes: Non-relative\u00a0<\/span><span><tt>JMP<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>CALL<\/tt><\/span><span>\u00a0have a\u00a0<\/span><span><tt>*<\/tt><\/span><span>\u00a0added to the syntax. Only\u00a0<\/span><span><tt>LOOP<\/tt><\/span><span>,\u00a0<\/span><span><tt>LOOPEQ<\/tt><\/span><span>, and\u00a0<\/span><span><tt>LOOPNE<\/tt><\/span><span>\u00a0are legal loop instructions. Only\u00a0<\/span><span><tt>REP<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>REPN<\/tt><\/span><span>\u00a0are recognized repeaters. These are not prefixes, but rather stand-alone opcodes that precede the strings, for example<\/span><\/p>\n<p><span data-section=\"6\" data-sentence=\"0\" data-group=\"6-0\" class=\"tgt color_text_0\">\u5176\u4ed6\u6ce8\u610f\u4e8b\u9879:\u975e\u76f8\u5bf9JMP\u548cCALL\u5728\u8bed\u6cd5\u4e2d\u6dfb\u52a0\u4e86*\u3002<\/span><span data-section=\"6\" data-sentence=\"1\" data-group=\"6-1\" class=\"tgt color_text_0\">\u53ea\u6709LOOP\u3001LOOPEQ\u548cLOOPNE\u662f\u5408\u6cd5\u7684\u5faa\u73af\u6307\u4ee4\u3002<\/span><span data-section=\"6\" data-sentence=\"2\" data-group=\"6-2\" class=\"tgt color_text_0\">\u53ea\u6709REP\u548cREPN\u662f\u53ef\u8bc6\u522b\u7684\u4e2d\u7ee7\u5668\u3002<\/span><span data-section=\"6\" data-sentence=\"3\" data-group=\"6-3\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0c\u8fd9\u4e9b\u4e0d\u662f\u524d\u7f00\uff0c\u800c\u662f\u4f4d\u4e8e\u5b57\u7b26\u4e32\u524d\u9762\u7684\u72ec\u7acb\u64cd\u4f5c\u7801<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0CLD;\u00a0REP;\u00a0MOVSL<\/tt><\/span><\/p>\n<p><span>Segment override prefixes in\u00a0<\/span><span><tt>MOD\/RM<\/tt><\/span><span>\u00a0fields are not supported.<\/span><\/p>\n<p><span>\u4e0d\u652f\u6301MOD\/RM\u5b57\u6bb5\u4e2d\u7684\u6bb5\u8986\u76d6\u524d\u7f00\u3002<\/span><\/p>\n<p><span><b>AMD64<\/b><\/span><\/p>\n<p><span>The assembler assumes 64-bit mode unless a\u00a0<\/span><span><tt>MODE<\/tt><\/span><span>\u00a0pseudo-operation is given:<\/span><\/p>\n<p><span>\u6c47\u7f16\u7a0b\u5e8f\u5047\u5b9a64\u4f4d\u6a21\u5f0f\uff0c\u9664\u975e\u7ed9\u51fa\u4e86mode\u4f2a\u64cd\u4f5c:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MODE\u00a0$32<\/tt><\/span><\/p>\n<p><span>to change to 32-bit mode. The effect is mainly to diagnose instructions that are illegal in the given mode, but the loader will also assume 32-bit operands and addresses, and 32-bit PC values for call and return. The assembler\u2019s conventions are similar to those for the 386, above. The architecture provides extra fixed-point registers\u00a0<\/span><span><tt>R8<\/tt><\/span><span>\u00a0to\u00a0<\/span><span><tt>R15<\/tt><\/span><span>. All registers are 64 bit, but instructions access low-order 8, 16 and 32 bits as described in the processor handbook. For example,\u00a0<\/span><span><tt>MOVL<\/tt><\/span><span>\u00a0to\u00a0<\/span><span><tt>AX<\/tt><\/span><span>\u00a0puts a value in the low-order 32 bits and clears the top 32 bits to zero. Literal operands are limited to signed 32 bit values, which are sign-extended to 64 bits in 64 bit operations; the exception is\u00a0<\/span><span><tt>MOVQ<\/tt><\/span><span>, which allows 64-bit literals. The external registers in Plan 9\u2019s C are allocated from\u00a0<\/span><span><tt>R15<\/tt><\/span><span>\u00a0down.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5207\u6362\u523032\u4f4d\u6a21\u5f0f\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5176\u4f5c\u7528\u4e3b\u8981\u662f\u8bca\u65ad\u5728\u7ed9\u5b9a\u6a21\u5f0f\u4e2d\u975e\u6cd5\u7684\u6307\u4ee4\uff0c\u4f46\u52a0\u8f7d\u5668\u4e5f\u5c06\u5047\u5b9a32\u4f4d\u64cd\u4f5c\u6570\u548c\u5730\u5740\uff0c\u4ee5\u53ca32\u4f4dPC\u503c\u7528\u4e8e\u8c03\u7528\u548c\u8fd4\u56de\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u7684\u7ea6\u5b9a\u7c7b\u4f3c\u4e8e\u4e0a\u9762386\u7684\u7ea6\u5b9a\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u8be5\u4f53\u7cfb\u7ed3\u6784\u63d0\u4f9b\u4e86\u989d\u5916\u7684\u5b9a\u70b9\u5bc4\u5b58\u5668R8\u5230R15\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u6240\u6709\u7684\u5bc4\u5b58\u5668\u90fd\u662f64\u4f4d\u7684\uff0c\u4f46\u662f\u5904\u7406\u5668\u624b\u518c\u4e2d\u63cf\u8ff0\u7684\u6307\u4ee4\u8bbf\u95ee\u4f4e\u96368\u4f4d\u300116\u4f4d\u548c32\u4f4d\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u4f8b\u5982\uff0cMOVL to AX\u5c06\u4e00\u4e2a\u503c\u653e\u5165\u4f4e\u963632\u4f4d\uff0c\u5e76\u5c06\u524d32\u4f4d\u6e05\u9664\u4e3a\u96f6\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u6587\u5b57\u64cd\u4f5c\u6570\u4ec5\u9650\u4e8e\u6709\u7b26\u53f7\u768432\u4f4d\u503c\uff0c\u572864\u4f4d\u64cd\u4f5c\u4e2d\u7b26\u53f7\u6269\u5c55\u4e3a64\u4f4d;<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">\u4f8b\u5916\u662fMOVQ\uff0c\u5b83\u5141\u8bb864\u4f4d\u6587\u5b57\u3002<\/span><span data-section=\"0\" data-sentence=\"8\" data-group=\"0-8\" class=\"tgt color_text_0\">\u8ba1\u52129\u7684C\u4e2d\u7684\u5916\u90e8\u5bc4\u5b58\u5668\u4eceR15\u5411\u4e0b\u5206\u914d\u3002<\/span><\/p>\n<p><span>There are many new instructions, including the MMX and XMM media instructions, and conditional move instructions. MMX registers are\u00a0<\/span><span><tt>M0<\/tt><\/span><span>\u00a0to\u00a0<\/span><span><tt>M7<\/tt><\/span><span>, and XMM registers are\u00a0<\/span><span><tt>X0<\/tt><\/span><span>\u00a0to\u00a0<\/span><span><tt>X15<\/tt><\/span><span>. As with the 386 instruction names, all new 64-bit integer instructions, and the MMX and XMM instructions uniformly use\u00a0<\/span><span><tt>L<\/tt><\/span><span>\u00a0for \u2018long word\u2019 (32 bits) and\u00a0<\/span><span><tt>Q<\/tt><\/span><span>\u00a0for \u2018quad word\u2019 (64 bits). Some instructions use\u00a0<\/span><span><tt>O<\/tt><\/span><span>\u00a0(\u2018octword\u2019) for 128-bit values, where the processor handbook variously uses\u00a0<\/span><span><tt>O<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>DQ<\/tt><\/span><span>. The assembler also consistently uses\u00a0<\/span><span><tt>PL<\/tt><\/span><span>\u00a0for \u2018packed long\u2019 in XMM instructions, instead of\u00a0<\/span><span><tt>Q<\/tt><\/span><span>,\u00a0<\/span><span><tt>DQ<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>PI<\/tt><\/span><span>. Either\u00a0<\/span><span><tt>MOVL<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>MOVQ<\/tt><\/span><span>\u00a0can be used to move values to and from control registers, even when the registers might be 64 bits. The assembler often accepts the handbook\u2019s name to ease conversion of existing code (but remember that the operand order is uniformly source then destination).<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6709\u8bb8\u591a\u65b0\u7684\u6307\u4ee4\uff0c\u5305\u62ecMMX\u548cXMM\u5a92\u4f53\u6307\u4ee4\uff0c\u4ee5\u53ca\u6709\u6761\u4ef6\u7684\u79fb\u52a8\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">MMX\u5bc4\u5b58\u5668\u662fM0\u5230M7, XMM\u5bc4\u5b58\u5668\u662fX0\u5230X15\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4e0e386\u6307\u4ee4\u540d\u4e00\u6837\uff0c\u6240\u6709\u65b0\u768464\u4f4d\u6574\u6570\u6307\u4ee4\uff0c\u4ee5\u53caMMX\u548cXMM\u6307\u4ee4\u7edf\u4e00\u4f7f\u7528L\u8868\u793a\u201c\u957f\u5b57\u201d(32\u4f4d)\uff0c\u4f7f\u7528Q\u8868\u793a\u201c\u56db\u5b57\u201d(64\u4f4d)\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u6709\u4e9b\u6307\u4ee4\u4f7f\u7528O (&#8216; octword &#8216;)\u8868\u793a128\u4f4d\u7684\u503c\uff0c\u800c\u5904\u7406\u5668\u624b\u518c\u5219\u4f7f\u7528O\u6216DQ\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u8fd8\u4e00\u81f4\u5730\u5728XMM\u6307\u4ee4\u4e2d\u4f7f\u7528PL\u6765\u8868\u793a\u201c\u5305\u88c5\u957f\u201d\uff0c\u800c\u4e0d\u662fQ\u3001DQ\u6216PI\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u65e0\u8bba\u662fMOVL\u8fd8\u662fMOVQ\u90fd\u53ef\u4ee5\u7528\u4e8e\u5728\u63a7\u5236\u5bc4\u5b58\u5668\u4e4b\u95f4\u79fb\u52a8\u503c\uff0c\u751a\u81f3\u5f53\u5bc4\u5b58\u5668\u53ef\u80fd\u662f64\u4f4d\u65f6\u4e5f\u662f\u5982\u6b64\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u901a\u5e38\u63a5\u53d7\u624b\u518c\u7684\u540d\u79f0\uff0c\u4ee5\u7b80\u5316\u73b0\u6709\u4ee3\u7801\u7684\u8f6c\u6362(\u4f46\u8bf7\u8bb0\u4f4f\uff0c\u64cd\u4f5c\u6570\u987a\u5e8f\u662f\u7edf\u4e00\u7684\u6e90\u540e\u76ee\u6807\u987a\u5e8f)\u3002<\/span><\/p>\n<p><span>C\u2019s\u00a0<\/span><span><tt>long<\/tt><\/span><span>\u00a0<\/span><span><tt>long<\/tt><\/span><span>\u00a0type is 64 bits, but passed and returned by value, not by reference. More notably, C pointer values are 64 bits, and thus\u00a0<\/span><span><tt>long<\/tt><\/span><span>\u00a0<\/span><span><tt>long<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>unsigned<\/tt><\/span><span>\u00a0<\/span><span><tt>long<\/tt><\/span><span>\u00a0<\/span><span><tt>long<\/tt><\/span><span>\u00a0are the only integer types wide enough to hold a pointer value. The C compiler and library use the XMM floating-point instructions, not the old 387 ones, although the latter are implemented by assembler and loader. Unlike the 386, the first integer or pointer argument is passed in a register, which is\u00a0<\/span><span><tt>BP<\/tt><\/span><span>\u00a0for an integer or pointer (it can be referred to in assembly code by the pseudonym\u00a0<\/span><span><tt>RARG<\/tt><\/span><span>).\u00a0<\/span><span><tt>AX<\/tt><\/span><span>\u00a0holds the return value from subroutines as before. Floating-point results are returned in\u00a0<\/span><span><tt>X0<\/tt><\/span><span>, although currently the first floating-point parameter is not passed in a register. All parameters less than 8 bytes in length have 8 byte slots reserved on the stack to preserve alignment and simplify variable-length argument list access, including the first parameter when passed in a register, even though bytes 4 to 7 are not initialized.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">C\u8bed\u8a00\u7684long &#8211; long\u7c7b\u578b\u662f64\u4f4d\uff0c\u4f46\u662f\u901a\u8fc7\u503c\u4f20\u9012\u548c\u8fd4\u56de\uff0c\u800c\u4e0d\u662f\u901a\u8fc7\u5f15\u7528\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u66f4\u503c\u5f97\u6ce8\u610f\u7684\u662f\uff0cC\u6307\u9488\u503c\u662f64\u4f4d\u7684\uff0c\u56e0\u6b64long long\u548cunsigned long long\u662f\u60df\u4e00\u5bbd\u5ea6\u8db3\u591f\u5bb9\u7eb3\u6307\u9488\u503c\u7684\u6574\u6570\u7c7b\u578b\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">C\u7f16\u8bd1\u5668\u548c\u5e93\u4f7f\u7528XMM\u6d6e\u70b9\u6307\u4ee4\uff0c\u800c\u4e0d\u662f\u65e7\u7684387\u6d6e\u70b9\u6307\u4ee4\uff0c\u5c3d\u7ba1\u540e\u8005\u662f\u7531\u6c47\u7f16\u5668\u548c\u52a0\u8f7d\u5668\u5b9e\u73b0\u7684\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u4e0e386\u4e0d\u540c\u7684\u662f\uff0c\u7b2c\u4e00\u4e2a\u6574\u6570\u6216\u6307\u9488\u53c2\u6570\u5728\u5bc4\u5b58\u5668\u4e2d\u4f20\u9012\uff0c\u5b83\u662f\u6574\u6570\u6216\u6307\u9488\u7684BP(\u5b83\u53ef\u4ee5\u5728\u7a0b\u5e8f\u96c6\u4ee3\u7801\u4e2d\u901a\u8fc7\u5316\u540dRARG\u5f15\u7528)\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">AX\u50cf\u4ee5\u524d\u4e00\u6837\u4fdd\u5b58\u5b50\u4f8b\u7a0b\u7684\u8fd4\u56de\u503c\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u5728X0\u4e2d\u8fd4\u56de\u6d6e\u70b9\u7ed3\u679c\uff0c\u5c3d\u7ba1\u76ee\u524d\u6ca1\u6709\u5728\u5bc4\u5b58\u5668\u4e2d\u4f20\u9012\u7b2c\u4e00\u4e2a\u6d6e\u70b9\u53c2\u6570\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u6240\u6709\u957f\u5ea6\u5c0f\u4e8e8\u5b57\u8282\u7684\u5f62\u53c2\u90fd\u5728\u5806\u6808\u4e0a\u4fdd\u75598\u4e2a\u5b57\u8282\u69fd\uff0c\u4ee5\u4fdd\u6301\u5bf9\u9f50\u5e76\u7b80\u5316\u53d8\u957f\u5b9e\u53c2\u5217\u8868\u8bbf\u95ee\uff0c\u5305\u62ec\u5728\u5bc4\u5b58\u5668\u4e2d\u4f20\u9012\u7684\u7b2c\u4e00\u4e2a\u5f62\u53c2\uff0c\u5373\u4f7f\u5b57\u82824\u52307\u6ca1\u6709\u521d\u59cb\u5316\u3002<\/span><\/p>\n<p><span><b>Power PC<\/b><\/span><\/p>\n<p><span>The Power PC follows the Plan 9 model set by the MIPS and SPARC, not the elaborate ABIs. The 32-bit instructions of the 60x and 8xx PowerPC architectures are supported; there is no support for the older POWER instructions. Registers are\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>R31<\/tt><\/span><span>.\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0is initialized to zero; this is done by C start up code and assumed by the compiler and loader.\u00a0<\/span><span><tt>R1<\/tt><\/span><span>\u00a0is the stack pointer.\u00a0<\/span><span><tt>R2<\/tt><\/span><span>\u00a0is the static base register, with value the address of\u00a0<\/span><span><tt>setSB(SB)<\/tt><\/span><span>.\u00a0<\/span><span><tt>R3<\/tt><\/span><span>\u00a0is the return register and also the register holding the first argument to a C function, with space reserved at\u00a0<\/span><span><tt>0(FP)<\/tt><\/span><span>\u00a0as on the MIPS.\u00a0<\/span><span><tt>R31<\/tt><\/span><span>\u00a0is the loader temporary. The external registers in Plan 9\u2019s C are allocated from\u00a0<\/span><span><tt>R30<\/tt><\/span><span>\u00a0down.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">Power PC\u9075\u5faaMIPS\u548cSPARC\u8bbe\u7f6e\u7684\u8ba1\u52129\u6a21\u578b\uff0c\u800c\u4e0d\u662f\u7cbe\u5fc3\u8bbe\u8ba1\u7684abi\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u652f\u630160x\u548c8xx PowerPC\u67b6\u6784\u768432\u4f4d\u6307\u4ee4;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4e0d\u652f\u6301\u65e7\u7684POWER\u6307\u4ee4\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u4eceR0\u5230R31\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">R0\u521d\u59cb\u5316\u4e3a\u96f6;<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u8fd9\u662f\u7531C\u542f\u52a8\u4ee3\u7801\u5b8c\u6210\u7684\uff0c\u5e76\u7531\u7f16\u8bd1\u5668\u548c\u52a0\u8f7d\u5668\u627f\u62c5\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">R1\u662f\u5806\u6808\u6307\u9488\u3002<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">R2\u662f\u9759\u6001\u57fa\u5bc4\u5b58\u5668\uff0c\u503c\u4e3asetSB(SB)\u7684\u5730\u5740\u3002<\/span><span data-section=\"0\" data-sentence=\"8\" data-group=\"0-8\" class=\"tgt color_text_0\">R3\u662f\u8fd4\u56de\u5bc4\u5b58\u5668\uff0c\u4e5f\u662f\u4fdd\u5b58C\u51fd\u6570\u7b2c\u4e00\u4e2a\u53c2\u6570\u7684\u5bc4\u5b58\u5668\uff0c\u4e0eMIPS\u4e0a\u4e00\u6837\uff0c\u7a7a\u95f4\u4fdd\u7559\u57280(FP)\u3002<\/span><span data-section=\"0\" data-sentence=\"9\" data-group=\"0-9\" class=\"tgt color_text_0\">R31\u662f\u4e34\u65f6\u52a0\u8f7d\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"10\" data-group=\"0-10\" class=\"tgt color_text_0\">\u8ba1\u52129\u7684C\u4e2d\u7684\u5916\u90e8\u5bc4\u5b58\u5668\u4eceR30\u5411\u4e0b\u5206\u914d\u3002<\/span><\/p>\n<p><span>Floating point registers are called\u00a0<\/span><span><tt>F0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>F31<\/tt><\/span><span>. By convention, several registers are initialized to specific values; this is done by the operating system.\u00a0<\/span><span><tt>F27<\/tt><\/span><span>\u00a0must be initialized to the value\u00a0<\/span><span><tt>0x4330000080000000<\/tt><\/span><span>\u00a0(used by float-to-int conversion),\u00a0<\/span><span><tt>F28<\/tt><\/span><span>\u00a0to the value 0.0,\u00a0<\/span><span><tt>F29<\/tt><\/span><span>\u00a0to 0.5,\u00a0<\/span><span><tt>F30<\/tt><\/span><span>\u00a0to 1.0, and\u00a0<\/span><span><tt>F31<\/tt><\/span><span>\u00a0to 2.0.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6d6e\u70b9\u5bc4\u5b58\u5668\u79f0\u4e3aF0\u5230F31\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6309\u7167\u7ea6\u5b9a\uff0c\u51e0\u4e2a\u5bc4\u5b58\u5668\u88ab\u521d\u59cb\u5316\u4e3a\u7279\u5b9a\u7684\u503c;<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u8fd9\u662f\u7531\u64cd\u4f5c\u7cfb\u7edf\u5b8c\u6210\u7684\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">F27\u5fc5\u987b\u521d\u59cb\u5316\u4e3a\u503c0x4330000080000000(\u7528\u4e8e\u6d6e\u70b9\u5230\u6574\u6570\u8f6c\u6362)\uff0cF28\u521d\u59cb\u5316\u4e3a\u503c0.0,F29\u521d\u59cb\u5316\u4e3a0.5,F30\u521d\u59cb\u5316\u4e3a1.0,F31\u521d\u59cb\u5316\u4e3a2.0\u3002<\/span><\/p>\n<p><span>As on the MIPS and SPARC, the assembler accepts arbitrary literals as operands to\u00a0<\/span><span><tt>MOVW<\/tt><\/span><span>, and also to\u00a0<\/span><span><tt>ADD<\/tt><\/span><span>\u00a0and others where \u2018immediate\u2019 variants exist, and the loader generates sequences of\u00a0<\/span><span><tt>addi<\/tt><\/span><span>,\u00a0<\/span><span><tt>addis<\/tt><\/span><span>,\u00a0<\/span><span><tt>oris<\/tt><\/span><span>, etc. as required. The register indirect addressing modes use the same syntax as the SPARC, including double indexing when allowed.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u5c31\u50cf\u5728MIPS\u548cSPARC\u4e0a\u4e00\u6837\uff0c\u6c47\u7f16\u7a0b\u5e8f\u63a5\u53d7\u4efb\u610f\u7684\u5b57\u9762\u91cf\u4f5c\u4e3aMOVW\u7684\u64cd\u4f5c\u6570\uff0c\u4e5f\u63a5\u53d7ADD\u548c\u5176\u4ed6\u5b58\u5728\u201c\u76f4\u63a5\u201d\u53d8\u4f53\u7684\u64cd\u4f5c\u6570\uff0c\u52a0\u8f7d\u7a0b\u5e8f\u6839\u636e\u9700\u8981\u751f\u6210addi\u3001addis\u3001oris\u7b49\u5e8f\u5217\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u95f4\u63a5\u5bfb\u5740\u6a21\u5f0f\u4f7f\u7528\u4e0eSPARC\u76f8\u540c\u7684\u8bed\u6cd5\uff0c\u5305\u62ec\u5141\u8bb8\u7684\u53cc\u7d22\u5f15\u3002<\/span><\/p>\n<p><span>The instruction names are generally derived from the Motorola ones, subject to slight transformation: the \u2018<\/span><span><tt>.<\/tt><\/span><span>\u2019 marking the setting of condition codes is replaced by\u00a0<\/span><span><tt>CC<\/tt><\/span><span>, and when the letter \u2018<\/span><span><tt>o<\/tt><\/span><span>\u2019 represents \u2018OE=1\u2019 it is replaced by\u00a0<\/span><span><tt>V<\/tt><\/span><span>. Thus\u00a0<\/span><span><tt>add<\/tt><\/span><span>,\u00a0<\/span><span><tt>addo.<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>subfzeo.<\/tt><\/span><span>\u00a0become\u00a0<\/span><span><tt>ADD<\/tt><\/span><span>,\u00a0<\/span><span><tt>ADDVCC<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>SUBFZEVCC<\/tt><\/span><span>. As well as the three-operand conditional branch instruction\u00a0<\/span><span><tt>BC<\/tt><\/span><span>, the assembler provides pseudo-instructions for the common cases:\u00a0<\/span><span><tt>BEQ<\/tt><\/span><span>,\u00a0<\/span><span><tt>BNE<\/tt><\/span><span>,\u00a0<\/span><span><tt>BGT<\/tt><\/span><span>,\u00a0<\/span><span><tt>BGE<\/tt><\/span><span>,\u00a0<\/span><span><tt>BLT<\/tt><\/span><span>,\u00a0<\/span><span><tt>BLE<\/tt><\/span><span>,\u00a0<\/span><span><tt>BVC<\/tt><\/span><span>, and\u00a0<\/span><span><tt>BVS<\/tt><\/span><span>. The unconditional branch instruction is\u00a0<\/span><span><tt>BR<\/tt><\/span><span>. Indirect branches use\u00a0<\/span><span><tt>(CTR)<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>(LR)<\/tt><\/span><span>\u00a0as target.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6307\u4ee4\u540d\u79f0\u901a\u5e38\u6765\u81ea\u6469\u6258\u7f57\u62c9\u7684\u540d\u79f0\uff0c\u7a0d\u52a0\u6539\u53d8:&#8217;\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u2019\u6807\u8bb0\u6761\u4ef6\u4ee3\u7801\u7684\u8bbe\u7f6e\u7528CC\u4ee3\u66ff\uff0c\u5f53\u5b57\u6bcd\u201co\u201d\u8868\u793a\u201cOE=1\u201d\u65f6\u7528v\u4ee3\u66ff\uff0c\u5373add, addo\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u548csubfzeo\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u53d8\u6210ADD, ADDVCC\u548cSUBFZEVCC\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\u9664\u4e86\u4e09\u64cd\u4f5c\u6570\u6761\u4ef6\u5206\u652f\u6307\u4ee4BC\u4e4b\u5916\uff0c\u6c47\u7f16\u7a0b\u5e8f\u8fd8\u4e3a\u5e38\u89c1\u60c5\u51b5\u63d0\u4f9b\u4f2a\u6307\u4ee4:BEQ\u3001BNE\u3001BGT\u3001BGE\u3001BLT\u3001BLE\u3001BVC\u548cBVS\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u65e0\u6761\u4ef6\u7684\u5206\u652f\u6307\u4ee4\u662fBR\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u95f4\u63a5\u5206\u652f\u4f7f\u7528(CTR)\u6216(LR)\u4f5c\u4e3a\u76ee\u6807\u3002<\/span><\/p>\n<p><span>Load or store operations are replaced by\u00a0<\/span><span><tt>MOV<\/tt><\/span><span>\u00a0variants in the usual way:\u00a0<\/span><span><tt>MOVW<\/tt><\/span><span>\u00a0(move word),\u00a0<\/span><span><tt>MOVH<\/tt><\/span><span>\u00a0(move halfword with sign extension), and\u00a0<\/span><span><tt>MOVB<\/tt><\/span><span>\u00a0(move byte with sign extension, a pseudo-instruction), with unsigned variants\u00a0<\/span><span><tt>MOVHZ<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>MOVBZ<\/tt><\/span><span>, and byte-reversing\u00a0<\/span><span><tt>MOVWBR<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>MOVHBR<\/tt><\/span><span>. \u2018Load or store with update\u2019 versions are\u00a0<\/span><span><tt>MOVWU<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVHU<\/tt><\/span><span>, and\u00a0<\/span><span><tt>MOVBZU<\/tt><\/span><span>. Load or store multiple is\u00a0<\/span><span><tt>MOVMW<\/tt><\/span><span>. The exceptions are the string instructions, which are\u00a0<\/span><span><tt>LSW<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>STSW<\/tt><\/span><span>, and the reservation instructions\u00a0<\/span><span><tt>lwarx<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>stwcx.<\/tt><\/span><span>, which are\u00a0<\/span><span><tt>LWAR<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>STWCCC<\/tt><\/span><span>, all with operands in the usual data-flow order. Floating-point load or store instructions are\u00a0<\/span><span><tt>FMOVD<\/tt><\/span><span>,\u00a0<\/span><span><tt>FMOVDU<\/tt><\/span><span>,\u00a0<\/span><span><tt>FMOVS<\/tt><\/span><span>, and\u00a0<\/span><span><tt>FMOVSU<\/tt><\/span><span>. The register to register move instructions\u00a0<\/span><span><tt>fmr<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>fmr.<\/tt><\/span><span>\u00a0are written\u00a0<\/span><span><tt>FMOVD<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>FMOVDCC<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u52a0\u8f7d\u6216\u5b58\u50a8\u64cd\u4f5c\u4ee5\u901a\u5e38\u7684\u65b9\u5f0f\u88abMOV\u53d8\u91cf\u66ff\u6362:MOVW(\u79fb\u52a8\u5355\u8bcd)\u3001MOVH(\u79fb\u52a8\u5e26\u7b26\u53f7\u6269\u5c55\u7684\u534a\u8bcd)\u548cMOVB(\u79fb\u52a8\u5e26\u7b26\u53f7\u6269\u5c55\u7684\u5b57\u8282\uff0c\u4e00\u79cd\u4f2a\u6307\u4ee4)\u3001\u65e0\u7b26\u53f7\u53d8\u91cfMOVHZ\u548cMOVBZ\u4ee5\u53ca\u5b57\u8282\u53cd\u8f6cMOVWBR\u548cMOVHBR\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u201c\u52a0\u8f7d\u6216\u5b58\u50a8\u4e0e\u66f4\u65b0\u201d\u7684\u7248\u672c\u662fMOVWU, MOVHU\u548cMOVBZU\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u52a0\u8f7d\u6216\u5b58\u50a8\u500d\u6570\u4e3aMOVMW\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u4f8b\u5916\u662f\u5b57\u7b26\u4e32\u6307\u4ee4\uff0c\u5b83\u4eec\u662fLSW\u548cSTSW\uff0c\u4ee5\u53ca\u9884\u8ba2\u6307\u4ee4lwarx\u548cstwcx\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">\uff0c\u5206\u522b\u662fLWAR\u548cSTWCCC\uff0c\u5b83\u4eec\u7684\u64cd\u4f5c\u6570\u90fd\u6309\u7167\u901a\u5e38\u7684\u6570\u636e\u6d41\u987a\u5e8f\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u6d6e\u70b9\u52a0\u8f7d\u6216\u5b58\u50a8\u6307\u4ee4\u6709FMOVD\u3001FMOVDU\u3001FMOVS\u548cFMOVSU\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u5bc4\u5b58\u5668\u7528\u4e8e\u6ce8\u518c\u79fb\u52a8\u6307\u4ee4fmr\u548cfmr\u3002<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">\u683c\u5f0f\u4e3aFMOVD\u548cFMOVDCC\u3002<\/span><\/p>\n<p><span>The assembler knows the commonly used special purpose registers:\u00a0<\/span><span><tt>CR<\/tt><\/span><span>,\u00a0<\/span><span><tt>CTR<\/tt><\/span><span>,\u00a0<\/span><span><tt>DEC<\/tt><\/span><span>,\u00a0<\/span><span><tt>LR<\/tt><\/span><span>,\u00a0<\/span><span><tt>MSR<\/tt><\/span><span>, and\u00a0<\/span><span><tt>XER<\/tt><\/span><span>. The rest, which are often architecture-dependent, are referenced as\u00a0<\/span><span><tt>SPR(n)<\/tt><\/span><span>. The segment registers of the 60x series are similarly\u00a0<\/span><span><tt>SEG(n)<\/tt><\/span><span>, but\u00a0<\/span><span><i>n<\/i><\/span><span>\u00a0can also be a register name, as in\u00a0<\/span><span><tt>SEG(R3)<\/tt><\/span><span>. Moves between special purpose registers and general purpose ones, when allowed by the architecture, are written as\u00a0<\/span><span><tt>MOVW<\/tt><\/span><span>, replacing\u00a0<\/span><span><tt>mfcr<\/tt><\/span><span>,\u00a0<\/span><span><tt>mtcr<\/tt><\/span><span>,\u00a0<\/span><span><tt>mfmsr<\/tt><\/span><span>,\u00a0<\/span><span><tt>mtmsr<\/tt><\/span><span>,\u00a0<\/span><span><tt>mtspr<\/tt><\/span><span>,\u00a0<\/span><span><tt>mfspr<\/tt><\/span><span>,\u00a0<\/span><span><tt>mftb<\/tt><\/span><span>, and many others.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u77e5\u9053\u5e38\u7528\u7684\u7279\u6b8a\u7528\u9014\u5bc4\u5b58\u5668:CR\u3001CTR\u3001DEC\u3001LR\u3001MSR\u548cXER\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5176\u4f59\u7684\u901a\u5e38\u4f9d\u8d56\u4e8e\u4f53\u7cfb\u7ed3\u6784\uff0c\u79f0\u4e3aSPR(n)\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">60x\u7cfb\u5217\u7684\u6bb5\u5bc4\u5b58\u5668\u7c7b\u4f3c\u4e8eSEG(n)\uff0c\u4f46n\u4e5f\u53ef\u4ee5\u662f\u5bc4\u5b58\u5668\u540d\uff0c\u5982SEG(R3)\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u5728\u67b6\u6784\u5141\u8bb8\u7684\u60c5\u51b5\u4e0b\uff0c\u7279\u6b8a\u7528\u9014\u5bc4\u5b58\u5668\u548c\u901a\u7528\u7528\u9014\u5bc4\u5b58\u5668\u4e4b\u95f4\u7684\u79fb\u52a8\u88ab\u5199\u4e3aMOVW\uff0c\u53d6\u4ee3mfcr\u3001mtcr\u3001mfmsr\u3001mtmsr\u3001mtspr\u3001mfspr\u3001mftb\u548c\u8bb8\u591a\u5176\u4ed6\u5bc4\u5b58\u5668\u3002<\/span><\/p>\n<p><span>The fields of the condition register\u00a0<\/span><span><tt>CR<\/tt><\/span><span>\u00a0are referenced as\u00a0<\/span><span><tt>CR(0)<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>CR(7)<\/tt><\/span><span>. They are used by the\u00a0<\/span><span><tt>MOVFL<\/tt><\/span><span>\u00a0(move field) pseudo-instruction, which produces\u00a0<\/span><span><tt>mcrf<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>mtcrf<\/tt><\/span><span>. For example:<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6761\u4ef6\u5bc4\u5b58\u5668CR\u7684\u5b57\u6bb5\u88ab\u5f15\u7528\u4e3aCR(0)\u5230CR(7)\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5b83\u4eec\u88abMOVFL(\u79fb\u52a8\u5b57\u6bb5)\u4f2a\u6307\u4ee4\u4f7f\u7528\uff0c\u5b83\u4ea7\u751fmcrf\u6216mtcrf\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u4f8b\u5982:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0CR(3),\u00a0CR(0)<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0R3,\u00a0CR(1)<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0R3,\u00a0$7,\u00a0CR<\/tt><\/span><\/p>\n<p><span>They are also accepted in the conditional branch instruction, for example<\/span><\/p>\n<p><span>\u4f8b\u5982\uff0c\u5b83\u4eec\u5728\u6761\u4ef6\u5206\u652f\u6307\u4ee4\u4e2d\u4e5f\u88ab\u63a5\u53d7<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0BEQ\u00a0CR(7),\u00a0label<\/tt><\/span><\/p>\n<p><span>Fields of the\u00a0<\/span><span><tt>FPSCR<\/tt><\/span><span>\u00a0are accessed using\u00a0<\/span><span><tt>MOVFL<\/tt><\/span><span>\u00a0in a similar way:<\/span><\/p>\n<p><span>\u4f7f\u7528MOVFL\u4ee5\u7c7b\u4f3c\u7684\u65b9\u5f0f\u8bbf\u95eeFPSCR\u7684\u5b57\u6bb5:<\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0FPSCR,\u00a0F0<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0F0,\u00a0FPSCR<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0F0,\u00a0$7,\u00a0FPSCR<\/tt><\/span><\/p>\n<p><span><tt>\u00a0\u00a0\u00a0\u00a0MOVFL\u00a0\u00a0\u00a0$0,\u00a0FPSCR(3)<\/tt><\/span><\/p>\n<p><span>producing\u00a0<\/span><span><tt>mffs<\/tt><\/span><span>,\u00a0<\/span><span><tt>mtfsf<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>mtfsfi<\/tt><\/span><span>, as appropriate.<\/span><\/p>\n<p><span>\u4ea7\u751fmffs, mtfsf\u6216mtfsfi\uff0c\u89c6\u60c5\u51b5\u800c\u5b9a\u3002<\/span><\/p>\n<p><span><b>ARM<\/b><\/span><\/p>\n<p><span>The assembler provides access to\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>R14<\/tt><\/span><span>\u00a0and the\u00a0<\/span><span><tt>PC<\/tt><\/span><span>. The stack pointer is\u00a0<\/span><span><tt>R13<\/tt><\/span><span>, the link register is\u00a0<\/span><span><tt>R14<\/tt><\/span><span>, and the static base register is\u00a0<\/span><span><tt>R12<\/tt><\/span><span>.\u00a0<\/span><span><tt>R0<\/tt><\/span><span>\u00a0is the return register and also the register holding the first argument to a subroutine. The external registers in Plan 9\u2019s C are allocated from\u00a0<\/span><span><tt>R10<\/tt><\/span><span>\u00a0down.\u00a0<\/span><span><tt>R11<\/tt><\/span><span>\u00a0is used by the loader as a temporary register. The assembler supports the\u00a0<\/span><span><tt>CPSR<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>SPSR<\/tt><\/span><span>\u00a0registers. It also knows about coprocessor registers\u00a0<\/span><span><tt>C0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>C15<\/tt><\/span><span>. Floating registers are\u00a0<\/span><span><tt>F0<\/tt><\/span><span>\u00a0through\u00a0<\/span><span><tt>F7<\/tt><\/span><span>,\u00a0<\/span><span><tt>FPSR<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>FPCR<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u901a\u8fc7R14\u63d0\u4f9b\u5bf9R0\u548cPC\u7684\u8bbf\u95ee\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u5806\u6808\u6307\u9488\u662fR13\uff0c\u94fe\u63a5\u5bc4\u5b58\u5668\u662fR14\uff0c\u9759\u6001\u57fa\u5bc4\u5b58\u5668\u662fR12\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">R0\u662f\u8fd4\u56de\u5bc4\u5b58\u5668\uff0c\u4e5f\u662f\u4fdd\u5b58\u5b50\u4f8b\u7a0b\u7b2c\u4e00\u4e2a\u53c2\u6570\u7684\u5bc4\u5b58\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u8ba1\u52129\u7684C\u4e2d\u7684\u5916\u90e8\u5bc4\u5b58\u5668\u662f\u4eceR10\u5411\u4e0b\u5206\u914d\u7684\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">R11\u88ab\u52a0\u8f7d\u5668\u7528\u4f5c\u4e34\u65f6\u5bc4\u5b58\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u652f\u6301CPSR\u548cSPSR\u5bc4\u5b58\u5668\u3002<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">\u5b83\u8fd8\u77e5\u9053\u534f\u5904\u7406\u5668\u5bc4\u5b58\u5668C0\u5230C15\u3002<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">\u6d6e\u52a8\u5bc4\u5b58\u5668\u662fF0\u5230F7, FPSR\u548cFPCR\u3002<\/span><\/p>\n<p><span>As with the other architectures, loads and stores are called\u00a0<\/span><span><tt>MOV<\/tt><\/span><span>, e.g.\u00a0<\/span><span><tt>MOVW<\/tt><\/span><span>\u00a0for load word or store word, and\u00a0<\/span><span><tt>MOVM<\/tt><\/span><span>\u00a0for load or store multiple, depending on the operands.<\/span><\/p>\n<p><span>\u4e0e\u5176\u4ed6\u4f53\u7cfb\u7ed3\u6784\u4e00\u6837\uff0c\u52a0\u8f7d\u548c\u5b58\u50a8\u88ab\u79f0\u4e3aMOV\uff0c\u4f8b\u5982\uff0cMOVW\u7528\u4e8e\u52a0\u8f7d\u5b57\u6216\u5b58\u50a8\u5b57\uff0cMOVM\u7528\u4e8e\u52a0\u8f7d\u6216\u5b58\u50a8\u591a\u4e2a\uff0c\u8fd9\u53d6\u51b3\u4e8e\u64cd\u4f5c\u6570\u3002<\/span><\/p>\n<p><span>Addressing modes are supported by suffixes to the instructions:\u00a0<\/span><span><tt>.IA<\/tt><\/span><span>\u00a0(increment after),\u00a0<\/span><span><tt>.IB<\/tt><\/span><span>\u00a0(increment before),\u00a0<\/span><span><tt>.DA<\/tt><\/span><span>\u00a0(decrement after), and\u00a0<\/span><span><tt>.DB<\/tt><\/span><span>\u00a0(decrement before). These can only be used with the\u00a0<\/span><span><tt>MOV<\/tt><\/span><span>\u00a0instructions. The move multiple instruction,\u00a0<\/span><span><tt>MOVM<\/tt><\/span><span>, defines a range of registers using brackets, e.g.\u00a0<\/span><span><tt>[R0-R12]<\/tt><\/span><span>. The special\u00a0<\/span><span><tt>MOVM<\/tt><\/span><span>\u00a0addressing mode bits\u00a0<\/span><span><tt>W<\/tt><\/span><span>,\u00a0<\/span><span><tt>U<\/tt><\/span><span>, and\u00a0<\/span><span><tt>P<\/tt><\/span><span>\u00a0are written in the same manner, for example,\u00a0<\/span><span><tt>MOVM.DB.W<\/tt><\/span><span>. A\u00a0<\/span><span><tt>.S<\/tt><\/span><span>\u00a0suffix allows a\u00a0<\/span><span><tt>MOVM<\/tt><\/span><span>\u00a0instruction to access user\u00a0<\/span><span><tt>R13<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>R14<\/tt><\/span><span>\u00a0when in another processor mode. Shifts and rotates in addressing modes are supported by binary operators\u00a0<\/span><span><tt>&lt;&lt;<\/tt><\/span><span>\u00a0(logical left shift),\u00a0<\/span><span><tt>&gt;&gt;<\/tt><\/span><span>\u00a0(logical right shift),\u00a0<\/span><span><tt>-&gt;<\/tt><\/span><span>\u00a0(arithmetic right shift), and\u00a0<\/span><span><tt>@&gt;<\/tt><\/span><span>\u00a0(rotate right); for example\u00a0<\/span><span><tt>R7&gt;&gt;R2<\/tt><\/span><span>or\u00a0<\/span><span><tt>R2@&gt;2<\/tt><\/span><span>. The assembler does not support indexing by a shifted expression; only names can be doubly indexed.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0 highlight\">\u5bfb\u5740\u6a21\u5f0f\u7531\u6307\u4ee4\u7684\u540e\u7f00\u652f\u6301:. ia(\u540e\u9762\u7684\u589e\u91cf)\uff0c. ib(\u524d\u9762\u7684\u589e\u91cf)\uff0c. da(\u540e\u9762\u7684\u9012\u51cf)\u548c. db(\u524d\u9762\u7684\u9012\u51cf)\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u8fd9\u4e9b\u53ea\u80fd\u4e0eMOV\u6307\u4ee4\u4e00\u8d77\u4f7f\u7528\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u79fb\u52a8\u591a\u91cd\u6307\u4ee4MOVM\u4f7f\u7528\u62ec\u53f7\u5b9a\u4e49\u4e86\u4e00\u4e2a\u5bc4\u5b58\u5668\u8303\u56f4\uff0c\u4f8b\u5982[R0-R12]\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u7279\u6b8a\u7684MOVM\u5bfb\u5740\u6a21\u5f0f\u4f4dW\u3001U\u548cP\u4ee5\u540c\u6837\u7684\u65b9\u5f0f\u5199\u5165\uff0c\u4f8b\u5982\uff0cMOVM. db .W\u3002<\/span><span data-section=\"0\" data-sentence=\"4\" data-group=\"0-4\" class=\"tgt color_text_0\">s\u540e\u7f00\u5141\u8bb8MOVM\u6307\u4ee4\u5728\u53e6\u4e00\u79cd\u5904\u7406\u5668\u6a21\u5f0f\u4e0b\u8bbf\u95ee\u7528\u6237R13\u548cR14\u3002<\/span><span data-section=\"0\" data-sentence=\"5\" data-group=\"0-5\" class=\"tgt color_text_0\">\u5bfb\u5740\u6a21\u5f0f\u4e2d\u7684\u79fb\u4f4d\u548c\u65cb\u8f6c\u7531\u4e8c\u8fdb\u5236\u8fd0\u7b97\u7b26&amp;lt;&amp;lt;<\/span><span data-section=\"0\" data-sentence=\"6\" data-group=\"0-6\" class=\"tgt color_text_0\">(\u903b\u8f91\u5de6\u79fb)\uff0c&amp;gt;&amp;gt;<\/span><span data-section=\"0\" data-sentence=\"7\" data-group=\"0-7\" class=\"tgt color_text_0\">(\u903b\u8f91\u53f3\u79fb)\uff0c-&amp;gt;<\/span><span data-section=\"0\" data-sentence=\"8\" data-group=\"0-8\" class=\"tgt color_text_0\">(\u7b97\u672f\u53f3\u79fb)\uff0c@&amp;gt;<\/span><span data-section=\"0\" data-sentence=\"9\" data-group=\"0-9\" class=\"tgt color_text_0\">(\u5411\u53f3\u65cb\u8f6c);<\/span><span data-section=\"0\" data-sentence=\"10\" data-group=\"0-10\" class=\"tgt color_text_0\">\u4f8b\u5982R7&amp;gt;&amp;gt; r2\u6216R2@&amp;gt;<\/span><span data-section=\"0\" data-sentence=\"11\" data-group=\"0-11\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u4e0d\u652f\u6301\u7528\u79fb\u4f4d\u7684\u8868\u8fbe\u5f0f\u8fdb\u884c\u7d22\u5f15;<\/span><span data-section=\"0\" data-sentence=\"12\" data-group=\"0-12\" class=\"tgt color_text_0\">\u53ea\u6709\u540d\u79f0\u53ef\u4ee5\u88ab\u53cc\u7d22\u5f15\u3002<\/span><\/p>\n<p><span>Any instruction can be followed by a suffix that makes the instruction conditional:\u00a0<\/span><span><tt>.EQ<\/tt><\/span><span>,\u00a0<\/span><span><tt>.NE<\/tt><\/span><span>, and so on, as in the ARM manual, with synonyms\u00a0<\/span><span><tt>.HS<\/tt><\/span><span>\u00a0(for\u00a0<\/span><span><tt>.CS<\/tt><\/span><span>) and\u00a0<\/span><span><tt>.LO<\/tt><\/span><span>\u00a0(for\u00a0<\/span><span><tt>.CC<\/tt><\/span><span>), for example\u00a0<\/span><span><tt>ADD.NE<\/tt><\/span><span>. Arithmetic and logical instructions can have a\u00a0<\/span><span><tt>.S<\/tt><\/span><span>\u00a0suffix, as ARM allows, to set condition codes.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">\u4efb\u4f55\u6307\u4ee4\u540e\u9762\u90fd\u53ef\u4ee5\u8ddf\u4e00\u4e2a\u540e\u7f00\uff0c\u4f7f\u8be5\u6307\u4ee4\u5177\u6709\u6761\u4ef6:. eq\uff0c . ne\u7b49\u7b49\uff0c\u5982ARM\u624b\u518c\u4e2d\u6240\u793a\uff0c\u8fd8\u6709\u540c\u4e49\u8bcd\u3002hs(\u8868\u793a\u3002cs)\u548c\u3002lo(\u8868\u793a\u3002cc)\uff0c\u4f8b\u5982ADD.NE\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u7b97\u672f\u548c\u903b\u8f91\u6307\u4ee4\u53ef\u4ee5\u6709\u4e00\u4e2a. s\u540e\u7f00\uff0c\u56e0\u4e3aARM\u5141\u8bb8\uff0c\u7528\u6765\u8bbe\u7f6e\u6761\u4ef6\u4ee3\u7801\u3002<\/span><\/p>\n<p><span>The syntax of the\u00a0<\/span><span><tt>MCR<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>MRC<\/tt><\/span><span>\u00a0coprocessor instructions is largely as in the manual, with the usual adjustments. The assembler directly supports only the ARM floating-point coprocessor operations used by the compiler:\u00a0<\/span><span><tt>CMP<\/tt><\/span><span>,\u00a0<\/span><span><tt>ADD<\/tt><\/span><span>,\u00a0<\/span><span><tt>SUB<\/tt><\/span><span>,\u00a0<\/span><span><tt>MUL<\/tt><\/span><span>, and\u00a0<\/span><span><tt>DIV<\/tt><\/span><span>, all with\u00a0<\/span><span><tt>F<\/tt><\/span><span>\u00a0or\u00a0<\/span><span><tt>D<\/tt><\/span><span>\u00a0suffix selecting single or double precision. Floating-point load or store become\u00a0<\/span><span><tt>MOVF<\/tt><\/span><span>\u00a0and\u00a0<\/span><span><tt>MOVD<\/tt><\/span><span>. Conversion instructions are also specified by moves:\u00a0<\/span><span><tt>MOVWD<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVWF<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVDW<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVWD<\/tt><\/span><span>,\u00a0<\/span><span><tt>MOVFD<\/tt><\/span><span>, and\u00a0<\/span><span><tt>MOVDF<\/tt><\/span><span>.<\/span><\/p>\n<p><span data-section=\"0\" data-sentence=\"0\" data-group=\"0-0\" class=\"tgt color_text_0\">MCR\u548cMRC\u534f\u5904\u7406\u5668\u6307\u4ee4\u7684\u8bed\u6cd5\u5728\u5f88\u5927\u7a0b\u5ea6\u4e0a\u4e0e\u624b\u518c\u4e2d\u7684\u4e00\u6837\uff0c\u53ea\u662f\u8fdb\u884c\u4e86\u901a\u5e38\u7684\u8c03\u6574\u3002<\/span><span data-section=\"0\" data-sentence=\"1\" data-group=\"0-1\" class=\"tgt color_text_0\">\u6c47\u7f16\u7a0b\u5e8f\u76f4\u63a5\u652f\u6301\u7f16\u8bd1\u5668\u4f7f\u7528\u7684ARM\u6d6e\u70b9\u534f\u5904\u7406\u5668\u64cd\u4f5c:CMP\u3001ADD\u3001SUB\u3001MUL\u548cDIV\uff0c\u6240\u6709\u8fd9\u4e9b\u64cd\u4f5c\u90fd\u5e26\u6709F\u6216D\u540e\u7f00\u9009\u62e9\u5355\u7cbe\u5ea6\u6216\u53cc\u7cbe\u5ea6\u3002<\/span><span data-section=\"0\" data-sentence=\"2\" data-group=\"0-2\" class=\"tgt color_text_0\">\u6d6e\u70b9\u52a0\u8f7d\u6216\u5b58\u50a8\u53d8\u6210\u4e86MOVF\u548cMOVD\u3002<\/span><span data-section=\"0\" data-sentence=\"3\" data-group=\"0-3\" class=\"tgt color_text_0\">\u8f6c\u6362\u6307\u4ee4\u4e5f\u7531move\u6307\u5b9a:MOVWD, MOVWF, MOVDW, MOVWD, MOVFD\u548cMOVDF\u3002<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Manual for the Plan 9 assembler\uff08Plan 9 \u6c47\u7f16\u624b\u518c\uff09 \u4f5c\u8005\uff1a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[99],"tags":[113,120],"class_list":["post-1295","post","type-post","status-publish","format-standard","hentry","category-go","tag-golang","tag-plan9"],"views":1753,"_links":{"self":[{"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/posts\/1295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/comments?post=1295"}],"version-history":[{"count":13,"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/posts\/1295\/revisions"}],"predecessor-version":[{"id":1309,"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/posts\/1295\/revisions\/1309"}],"wp:attachment":[{"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/media?parent=1295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/categories?post=1295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mustenaka.cn\/index.php\/wp-json\/wp\/v2\/tags?post=1295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}