{"id":938,"date":"2016-02-06T20:11:48","date_gmt":"2016-02-06T12:11:48","guid":{"rendered":"http:\/\/qing.su\/?p=938"},"modified":"2016-02-06T20:27:01","modified_gmt":"2016-02-06T12:27:01","slug":"119","status":"publish","type":"post","link":"https:\/\/qing.su\/article\/119.html","title":{"rendered":"\u79d1\u666e\u5411\u2014\u2014\u4f7f\u7528BrainFuck\u8bed\u8a00\u7f16\u5199\u7b80\u5355\u7f51\u9875"},"content":{"rendered":"<p>\u4eca\u5929\u82b1\u4e86\u534a\u4e2a\u5c0f\u65f6\u7528BrainFuck\u8bed\u8a00\u7f16\u5199\u4e86\u4e00\u4e2a\u53ea\u6709\u4e00\u884c\u5b57\u7684\u7f51\u9875\uff08\u540c\u6837\u7684\u4e8b\u60c5\u5982\u679c\u7528C\u8bed\u8a00\u5927\u6982\u9700\u8981\u82b15\u5206\u949f\uff0c\u7528PHP\u53ea\u9700\u898120\u79d2\u949f\uff09\uff0c\u5927\u6982\u6ca1\u4eba\u6bd4\u6211\u66f4\u65e0\u804a\u4e86\u5427\u3002\u5730\u5740\u662f<a href=\"http:\/\/qing.su\/cgi-bin\/brainfuck.cgi\" target=\"_blank\">http:\/\/qing.su\/cgi-bin\/brainfuck.cgi<\/a><\/p>\n<p>BrainFuck\u662f\u4e16\u754c\u4e0a\u6700\u7cbe\u81f4\u7684\u56fe\u7075\u5b8c\u5907\u7684\u8ba1\u7b97\u673a\u8bed\u8a00\uff08\u5176\u7f16\u8bd1\u5668\u4ec5\u6709240bytes\uff09\u3002\u5b83\u7531\u516b\u4e2a\u5b57\u7b26\u6784\u6210\uff1a<>+-.,[]\u5206\u522b\u4ee3\u8868\u4e86\u5de6\u53f3\u4f4d\u79fb\u3001\u589e\u51cf\u53d8\u91cf\u3001\u8f93\u51fa\u8f93\u5165\u4ee5\u53ca\u5faa\u73af\u5f00\u95ed\u3002\u5982\u6b64\u6709\u9650\u7684\u5b57\u7b26\u5e93\u51b3\u5b9a\u4e86\u5176\u7f16\u5199\u8fc7\u7a0b\u7684\u7e41\u7410\u548c\u5197\u957f\u3001\u6613\u8bfb\u6027\u6781\u5dee\uff0c\u51e0\u4e4e\u65e0\u6cd5\u6210\u4e3a\u771f\u6b63\u751f\u4ea7\u4f7f\u7528\u7684\u8ba1\u7b97\u673a\u8bed\u8a00\u3002\u6216\u8bb8\uff0c\u5076\u5c14\u7f16\u5199\u4e00\u4e2aBrainFuck\u7a0b\u5e8f\u70e7\u4e00\u70e7\u8111\u5b50\u662f\u4e0d\u9519\u7684\u9009\u62e9\u3002\u4e0b\u9762\u4ecb\u7ecd\u4e00\u4e0b\u7528BrainFuck\u8bed\u8a00\u7f16\u5199\u7f51\u9875\u7684\u65b9\u5f0f\u3002<!--more--><\/p>\n<p>\u5f00\u59cb\u7f16\u5199\u7f51\u9875\u4e4b\u524d\uff0c\u9700\u8981\u4e86\u89e3\u4e00\u4e0bCGI\u7f16\u7a0b\u89c4\u8303\u3002\u4efb\u4f55\u4e00\u79cd\u8bed\u8a00\u7f16\u5199\u7684\u7a0b\u5e8f\u90fd\u53ef\u4ee5\u6210\u4e3a\u7f51\u9875\u3002\u5982PHP, JSP\u4e4b\u7c7b\u7684\u7a0b\u5e8f\u53ef\u4ee5\u901a\u8fc7\u5bf9\u5e94\u7684\u811a\u672c\u89e3\u91ca\u5668\u8f6c\u6362\u4e3aHTML\u6807\u7b7e\u683c\u5f0f\uff0c\u76f4\u63a5\u5448\u73b0\u5728\u6d4f\u89c8\u5668\u4e0a\u4f9b\u4eba\u4eec\u8bbf\u95ee\u3002\u800c\u5982\u679c\u4f7f\u7528\u5176\u4ed6\u975e\u4e3b\u6d41\u8bed\u8a00\uff0c\u6bd4\u5982\u4e4b\u524d\u63d0\u5230\u7684C\u8bed\u8a00\uff08\u53c2\u8003 <a href=\"http:\/\/qing.su\/article\/93.html\" target=\"_blank\">http:\/\/qing.su\/article\/93.html<\/a>\uff09\u6216\u8005\u6b63\u5728\u4f7f\u7528\u7684BrainFuck\u8bed\u8a00\uff0c\u5219\u53ef\u4ee5\u901a\u8fc7CGI\u7684\u65b9\u5f0f\u8bbf\u95ee\uff0c\u8ba9\u670d\u52a1\u5668\u5c06\u7a0b\u5e8f\u8f6c\u5316\u4e3aHTML\u6807\u7b7e\u63d0\u4f9b\u7ed9\u5ba2\u6237\u7aef\u6d4f\u89c8\u5668\u8bc6\u522b\u3002\u6309\u7167CGI\u7684\u8981\u6c42\uff0c\u8f93\u51fa\u5230\u6d4f\u89c8\u5668\u4e0a\u7684\u7a0b\u5e8f\u9700\u8981\u9996\u5148\u63d0\u4ea4\u5934\u4fe1\u606f\uff0c\u6bd4\u5982\uff0cContent-type: text\/html, \u5e76\u4e14\u5728\u5934\u4fe1\u606f\u4e0b\u90e8\u6709\u4e00\u7a7a\u884c\u3002\u56e0\u6b64\uff0c\u53ea\u8981\u9075\u5faa\u8fd9\u4e00\u89c4\u8303\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u7528\u4efb\u4f55\u8bed\u8a00\u7684\u7a0b\u5e8f\u7f16\u5199\u7f51\u9875\u3002<\/p>\n<p>\u9996\u5148\uff0c\u7f16\u5199\u4e00\u4e2aBrainFuck\u8bed\u8a00\u7a0b\u5e8f\uff0c\u5982\u4e0b\u3002<\/p>\n<div class=\"codecolorer-container text geshi\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/><\/div><\/td><td><div class=\"text codecolorer\" style=\"white-space:nowrap\">++++++++++ &nbsp; * \u53d8\u91cf\u7b2c\u96f6\u4f4d+10, \u50a8\u5b58\u5faa\u73af\u6b21\u6570<br \/>\n[&gt;+++++++++++ &nbsp; * \u53d8\u91cf\u7b2c\u4e00\u4f4d+11, 10*11=110 == asc('n')<br \/>\n&gt;++++++++++++&gt;+++&gt;++++++&gt;+++++++&gt;++++++++&gt;+&gt;++++ &nbsp; * \u7c7b\u4f3c\u4e0a\u4e00\u6b65\uff0c\u8bbe\u7f6e8\u4e2a\u53d8\u91cf\u65b9\u4fbf\u8f93\u51fa\u5b57\u7b26<br \/>\n&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;-] &nbsp; * \u5faa\u73af\uff0c\u6bcf\u6b21\u5faa\u73af\u7b2c\u4e00\u4f4d\u53d8\u91cf-1, \u76f4\u81f30<br \/>\n&gt;&gt;&gt;&gt;&gt;---. &nbsp; * \u7b2c\u4e94\u4f4d\u53d8\u91cf-3, \u8f93\u51fa10*7-3=67 == asc('C')<br \/>\n&lt;&lt;&lt;&lt;+. &nbsp; * \u7b2c\u4e00\u4f4d\u53d8\u91cf+1, \u8f93\u51fa10*11+1=111 == asc('o')<br \/>\n-. &nbsp; * \u7b2c\u4e00\u4f4d\u53d8\u91cf-1, 110 'n'<br \/>\n&gt;----. &nbsp; * \u7b2c\u4e8c\u4f4d\u53d8\u91cf-4, 10*12-4=116 == asc('t')<br \/>\n&lt;---------. &nbsp; * \u7b2c\u4e00\u4f4d\u53d8\u91cf-9, 101 'e'<br \/>\n+++++++++.&gt;.&gt;&gt;&gt;&gt;&gt;&gt;+++++.<br \/>\n&lt;&lt;&lt;&lt;&lt;&lt;.+++++.&lt;++.-----------.<br \/>\n&gt;&gt;&gt;--.&lt;++.&lt;-----.&lt;.&gt;++++.----.<br \/>\n&gt;&gt;&gt;&gt;&gt;&gt;++.&lt;&lt;&lt;&lt;&lt;&lt;&lt;+++.&gt;.&lt;+++++.-.<br \/>\n&gt;&gt;&gt;&gt;&gt;&gt;..&lt;&lt;+++++.--&lt;+++++++.&gt;&gt;..<br \/>\n+++++++++.&lt;&lt;&lt;.&gt;&gt;++++++++.--&lt;++++.++++++++++++++++++.<br \/>\n------------------&gt;&gt;--&lt;&lt;&lt;.<br \/>\n&gt;&gt;&gt;++.&lt;&lt;.----.&gt;++++++.&lt;&lt;+. &nbsp; &nbsp;* \u7ee7\u7eed\u4e4b\u524d\u7684\u8f93\u51fa<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>\u8fd9\u4e2a\u7a0b\u5e8f\u505a\u4e86\u4e24\u4ef6\u4e8b\uff1a1\uff0c\u5411\u670d\u52a1\u5668\u8f93\u51faContent-type: text\/html\\n\\n. 2\uff0c\u5411\u670d\u52a1\u5668\u8f93\u51fa\u9700\u8981\u663e\u793a\u5728\u5c4f\u5e55\u4e0a\u7684\u53e5\u5b50\uff0cHAPPY NEW YEAR! <\/p>\n<p>\u7f16\u5199\u5b8c\u6bd5\u540e\uff0c\u6211\u4eec\u5728\u670d\u52a1\u5668\u4e0a\u5c06\u5176\u7f16\u8bd1\u4e3a\u53ef\u6267\u884c\u7a0b\u5e8f\u3002\u7f16\u8bd1\u5668\u4e3a\u6c47\u7f16\u6e90\u7801\uff08\u94fe\u63a5\u4e3a\uff1ahttp:\/\/www.muppetlabs.com\/~breadbox\/software\/tiny\/bf.asm.txt\uff09\uff0c\u53ef\u4ee5\u7528nasm\u7a0b\u5e8f\u5c06\u5176\u7f16\u8bd1\u6210\u53ef\u6267\u884c\u7a0b\u5e8f\u3002\u65b0\u5efa\u6587\u4ef6bf.asm\u5c06\u6e90\u7801\u4fdd\u5b58\u5728\u5176\u4e2d\uff1a<\/p>\n<div class=\"codecolorer-container asm geshi\" style=\"overflow:auto;white-space:nowrap;height:300px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/>28<br \/>29<br \/>30<br \/>31<br \/>32<br \/>33<br \/>34<br \/>35<br \/>36<br \/>37<br \/>38<br \/>39<br \/>40<br \/>41<br \/>42<br \/>43<br \/>44<br \/>45<br \/>46<br \/>47<br \/>48<br \/>49<br \/>50<br \/>51<br \/>52<br \/>53<br \/>54<br \/>55<br \/>56<br \/>57<br \/>58<br \/>59<br \/>60<br \/>61<br \/>62<br \/>63<br \/>64<br \/>65<br \/>66<br \/>67<br \/>68<br \/>69<br \/>70<br \/>71<br \/>72<br \/>73<br \/>74<br \/>75<br \/>76<br \/>77<br \/>78<br \/>79<br \/>80<br \/>81<br \/>82<br \/>83<br \/>84<br \/>85<br \/>86<br \/>87<br \/>88<br \/>89<br \/>90<br \/>91<br \/>92<br \/>93<br \/>94<br \/>95<br \/>96<br \/>97<br \/>98<br \/>99<br \/>100<br \/>101<br \/>102<br \/>103<br \/>104<br \/>105<br \/>106<br \/>107<br \/>108<br \/>109<br \/>110<br \/>111<br \/>112<br \/>113<br \/>114<br \/>115<br \/>116<br \/>117<br \/>118<br \/>119<br \/>120<br \/>121<br \/>122<br \/>123<br \/>124<br \/>125<br \/>126<br \/>127<br \/>128<br \/>129<br \/>130<br \/>131<br \/>132<br \/>133<br \/>134<br \/>135<br \/>136<br \/>137<br \/>138<br \/>139<br \/>140<br \/>141<br \/>142<br \/>143<br \/>144<br \/>145<br \/>146<br \/>147<br \/>148<br \/>149<br \/>150<br \/>151<br \/>152<br \/>153<br \/>154<br \/>155<br \/>156<br \/>157<br \/>158<br \/>159<br \/>160<br \/>161<br \/>162<br \/>163<br \/>164<br \/>165<br \/>166<br \/>167<br \/>168<br \/>169<br \/>170<br \/>171<br \/>172<br \/>173<br \/>174<br \/>175<br \/>176<br \/>177<br \/>178<br \/>179<br \/>180<br \/>181<br \/>182<br \/>183<br \/>184<br \/>185<br \/>186<br \/>187<br \/>188<br \/>189<br \/>190<br \/>191<br \/>192<br \/>193<br \/>194<br \/>195<br \/>196<br \/>197<br \/>198<br \/>199<br \/>200<br \/>201<br \/>202<br \/>203<br \/>204<br \/>205<br \/>206<br \/>207<br \/>208<br \/>209<br \/>210<br \/>211<br \/>212<br \/>213<br \/>214<br \/>215<br \/>216<br \/>217<br \/>218<br \/>219<br \/>220<br \/>221<br \/>222<br \/>223<br \/>224<br \/>225<br \/>226<br \/>227<br \/>228<br \/>229<br \/>230<br \/>231<br \/>232<br \/>233<br \/>234<br \/>235<br \/>236<br \/>237<br \/>238<br \/>239<br \/>240<br \/>241<br \/>242<br \/>243<br \/>244<br \/>245<br \/>246<br \/>247<br \/>248<br \/>249<br \/>250<br \/>251<br \/>252<br \/>253<br \/>254<br \/>255<br \/>256<br \/>257<br \/>258<br \/>259<br \/>260<br \/>261<br \/>262<br \/>263<br \/>264<br \/>265<br \/>266<br \/>267<br \/>268<br \/>269<br \/><\/div><\/td><td><div class=\"asm codecolorer\" style=\"white-space:nowrap\"><span style=\"color: #666666; font-style: italic;\">;; bf.asm: Copyright (C) 1999 Brian Raiter &lt;breadbox@muppetlabs.com&gt;<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; Licensed under the terms of the GNU General Public License, either<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; version 2 or (at your option) any later version.<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;;<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; To build:<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;;&nbsp; nasm -f bin -o bf bf.asm &amp;&amp; chmod +x bf<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; To use:<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;;&nbsp; bf &lt; foo.b &gt; foo &amp;&amp; chmod +x foo<\/span><br \/>\n<br \/>\n<span style=\"color: #0000ff; font-weight: bold;\">BITS<\/span> <span style=\"color: #ff0000;\">32<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; This is the size of the data area supplied to compiled programs.<\/span><br \/>\n<br \/>\n<span style=\"color: #0000ff; font-weight: bold;\">%define<\/span> arraysize &nbsp; <span style=\"color: #ff0000;\">30000<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; For the compiler, the text segment is also the data segment. The<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; memory image of the compiler is inside the code buffer, and is<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; modified in place to become the memory image of the compiled<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; program. The area of memory that is the data segment for compiled<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; programs is not used by the compiler. The text and data segments of<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; compiled programs are really only different areas in a single<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; segment, from the system's point of view. Both the compiler and<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; compiled programs load the entire file contents into a single<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; memory segment which is both writeable and executable.<\/span><br \/>\n<br \/>\n<span style=\"color: #0000ff; font-weight: bold;\">%define<\/span> TEXTORG &nbsp; &nbsp; <span style=\"color: #ff0000;\">0x45E9B000<\/span><br \/>\n<span style=\"color: #0000ff; font-weight: bold;\">%define<\/span> DATAOFFSET&nbsp; <span style=\"color: #ff0000;\">0x2000<\/span><br \/>\n<span style=\"color: #0000ff; font-weight: bold;\">%define<\/span> DATAORG &nbsp; &nbsp; <span style=\"color: #009900; font-weight: bold;\">&#40;<\/span>TEXTORG <span style=\"color: #339933;\">+<\/span> DATAOFFSET<span style=\"color: #009900; font-weight: bold;\">&#41;<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; Here begins the file image.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; org TEXTORG<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; At the beginning of the text segment is the ELF header and the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; program header table, the latter consisting of a single entry. The<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; two structures overlap for a space of eight bytes. Nearly all<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; unused fields in the structures are used to hold bits of code.<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The beginning of the ELF header.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">db<\/span>&nbsp; <span style=\"color: #ff0000;\">0x7F<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #7f007f;\">&quot;ELF&quot;<\/span> &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_ident<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The top(s) of the main compiling loop. The loop jumps back to<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; different positions, depending on how many bytes to copy into the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; code buffer. After doing that, esi is initialized to point to the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; epilog code chunk, a copy of edi (the pointer to the end of the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; code buffer) is saved in ebp, the high bytes of eax are reset to<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; zero (via the exchange with ebx), and then the next character of<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; input is retrieved.<\/span><br \/>\n<br \/>\nemitputchar<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">add<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #0000ff; font-weight: bold;\">byte<\/span> <span style=\"color: #009900; font-weight: bold;\">&#40;<\/span>putchar <span style=\"color: #339933;\">-<\/span> decchar<span style=\"color: #009900; font-weight: bold;\">&#41;<\/span> <span style=\"color: #339933;\">-<\/span> <span style=\"color: #ff0000;\">4<\/span><br \/>\nemitgetchar<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">lodsd<\/span><br \/>\nemit6bytes<span style=\"color: #339933;\">:<\/span> <span style=\"color: #b00040;\">movsd<\/span><br \/>\nemit2bytes<span style=\"color: #339933;\">:<\/span> <span style=\"color: #00007f; font-weight: bold;\">movsb<\/span><br \/>\nemit1byte<span style=\"color: #339933;\">:<\/span>&nbsp; <span style=\"color: #00007f; font-weight: bold;\">movsb<\/span><br \/>\ncompile<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">lea<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #0000ff; font-weight: bold;\">byte<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span> <span style=\"color: #339933;\">+<\/span> epilog <span style=\"color: #339933;\">-<\/span> filesize<span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">xchg<\/span>&nbsp; &nbsp; <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ebx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">cmp<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #ff0000;\">0x00030002<\/span> &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_type &nbsp; &nbsp;(0x0002)<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_machine (0x0003)<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ebp<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edi<\/span>&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_version<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jmp<\/span> short getchar<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The entry point for the compiler (and compiled programs), and the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; location of the program header table.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dd<\/span>&nbsp; _start&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_entry<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dd<\/span>&nbsp; proghdr <span style=\"color: #339933;\">-<\/span> <span style=\"color: #0000ff; font-weight: bold;\">$$<\/span>&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_phoff<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The last routine of the compiler, called when there is no more<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; input. The epilog code chunk is copied into the code buffer. The<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; text origin is popped off the stack into ecx, and subtracted from<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; edi to determine the size of the compiled program. This value is<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; stored in the program header table, and then is moved into edx.<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The program then jumps to the putchar routine, which sends the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; compiled program to stdout before falling through to the epilog<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; routine and exiting.<\/span><br \/>\n<br \/>\neof<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #b00040;\">movsd<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_shoff<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">xchg<\/span>&nbsp; &nbsp; <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">pop<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">sub<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edi<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span>&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_flags<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">xchg<\/span>&nbsp; &nbsp; <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edi<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">stosd<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">xchg<\/span>&nbsp; &nbsp; <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jmp<\/span> short putchar &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_ehsize<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; 0x20 == the size of one program header table entry.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dw<\/span>&nbsp; <span style=\"color: #ff0000;\">0x20<\/span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_phentsize<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The beginning of the program header table. 1 == PT_LOAD, indicating<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; that the segment is to be loaded into memory.<\/span><br \/>\n<br \/>\nproghdr<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dd<\/span>&nbsp; <span style=\"color: #ff0000;\">1<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_phnum &amp; phdr.p_type<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_shentsize<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dd<\/span>&nbsp; <span style=\"color: #ff0000;\">0<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_shnum &amp; phdr.p_offset<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; ehdr.e_shstrndx<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; (Note that the next four bytes, in addition to containing the first<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; two instructions of the bracket routine, also comprise the memory<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; address of the text origin.)<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">db<\/span>&nbsp; <span style=\"color: #ff0000;\">0<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; phdr.p_vaddr<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The bracket routine emits code for the &quot;[&quot; instruction. This<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; instruction translates to a simple &quot;jmp near&quot;, but the target of<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; the jump will not be known until the matching &quot;]&quot; is seen. The<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; routine thus outputs a random target, and pushes the location of<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; the target in the code buffer onto the stack.<\/span><br \/>\n<br \/>\nbracket<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #ff0000;\">0xE9<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ebp<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">push<\/span>&nbsp; &nbsp; <span style=\"color: #46aa03; font-weight: bold;\">ebp<\/span> &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; phdr.p_paddr<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">stosd<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jmp<\/span> short emit1byte<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; This is where the size of the executable file is stored in the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; program header table. The compiler updates this value just before<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; it outputs the compiled program. This is the only field in the two<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; headers that differs between the compiler and its compiled<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; programs. (While the compiler is reading input, the first byte of<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; this field is also used as an input buffer.)<\/span><br \/>\n<br \/>\nfilesize<span style=\"color: #339933;\">:<\/span> &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dd<\/span>&nbsp; compilersize&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; phdr.p_filesz<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The size of the program in memory. This entry creates an area of<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; bytes, arraysize in size, all initialized to zero, starting at<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; DATAORG.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">dd<\/span>&nbsp; DATAOFFSET <span style=\"color: #339933;\">+<\/span> arraysize&nbsp; <span style=\"color: #666666; font-style: italic;\">; phdr.p_memsz<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The code chunk for the &quot;.&quot; instruction. eax is set to 4 to invoke<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; the write system call. ebx, the file handle to write to, is set to<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; 1 for stdout. ecx points to the buffer containing the bytes to<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; output, and edx equals the number of bytes to output. (Note that<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; the first byte of the first instruction, which is also the least<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; significant byte of the p_flags field, encodes to 0xB3. Having the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; 2-bit set marks the memory containing the compiler, and its<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; compiled programs, as writeable.)<\/span><br \/>\n<br \/>\nputchar<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">bl<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #ff0000;\">1<\/span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; phdr.p_flags<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #ff0000;\">4<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">int<\/span> <span style=\"color: #ff0000;\">0x80<\/span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #666666; font-style: italic;\">; phdr.p_align<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The epilog code chunk. After restoring the initialized registers,<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; eax and ebx are both zero. eax is incremented to 1, so as to invoke<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; the exit system call. ebx specifies the process's return value.<\/span><br \/>\n<br \/>\nepilog<span style=\"color: #339933;\">:<\/span> &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">popa<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">int<\/span> <span style=\"color: #ff0000;\">0x80<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The code chunks for the &quot;&gt;&quot;, &quot;&lt;&quot;, &quot;+&quot;, and &quot;-&quot; instructions.<\/span><br \/>\n<br \/>\nincptr<span style=\"color: #339933;\">:<\/span> &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><br \/>\ndecptr<span style=\"color: #339933;\">:<\/span> &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">dec<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><br \/>\nincchar<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #0000ff; font-weight: bold;\">byte<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><br \/>\n<span style=\"color: #adadad; font-style: italic;\">decc<\/span>har<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">dec<\/span> <span style=\"color: #0000ff; font-weight: bold;\">byte<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The main loop of the compiler continues here, by obtaining the next<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; character of input. This is also the code chunk for the &quot;,&quot;<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; instruction. eax is set to 3 to invoke the read system call. ebx,<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; the file handle to read from, is set to 0 for stdin. ecx points to<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; a buffer to receive the bytes that are read, and edx equals the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; number of bytes to read.<\/span><br \/>\n<br \/>\ngetchar<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #ff0000;\">3<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">xor<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ebx<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ebx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">int<\/span> <span style=\"color: #ff0000;\">0x80<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; If eax is zero or negative, then there is no more input, and the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; compiler proceeds to the eof routine.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">or<\/span>&nbsp; <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jle<\/span> eof<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; Otherwise, esi is advanced four bytes (from the epilog code chunk<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; to the incptr code chunk), and the character read from the input is<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; stored in al, with the high bytes of eax reset to zero.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">lodsd<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The compiler compares the input character with &quot;&gt;&quot; and &quot;&lt;&quot;. esi is<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; advanced to the next code chunk with each failed test.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">cmp<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #7f007f;\">'&gt;'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; emit1byte<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">cmp<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #7f007f;\">'&lt;'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; emit1byte<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The next four tests check for the characters &quot;+&quot;, &quot;,&quot;, &quot;-&quot;, and<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; &quot;.&quot;, respectively. These four characters are contiguous in ASCII,<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; and so are tested for by doing successive decrements of eax.<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">sub<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #7f007f;\">'+'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; emit2bytes<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">dec<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; emitgetchar<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">dec<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; emit2bytes<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">dec<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; emitputchar<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The remaining instructions, &quot;[&quot; and &quot;]&quot;, have special routines for<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; emitting the proper code. (Note that the jump back to the main loop<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; is at the edge of the short-jump range. Routines below here<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; therefore use this jump as a relay to return to the main loop;<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; however, in order to use it correctly, the routines must be sure<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; that the zero flag is cleared at the time.)<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">cmp<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #7f007f;\">'['<\/span> <span style=\"color: #339933;\">-<\/span> <span style=\"color: #7f007f;\">'.'<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jz<\/span>&nbsp; bracket<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">cmp<\/span> <span style=\"color: #46aa03; font-weight: bold;\">al<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #7f007f;\">']'<\/span> <span style=\"color: #339933;\">-<\/span> <span style=\"color: #7f007f;\">'.'<\/span><br \/>\nrelay<span style=\"color: #339933;\">:<\/span>&nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jnz<\/span> compile<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; The endbracket routine emits code for the &quot;]&quot; instruction, as well<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; as completing the code for the matching &quot;[&quot;. The compiler first<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; emits &quot;cmp dh, [ecx]&quot; and the first two bytes of a &quot;jnz near&quot;. The<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; location of the missing target in the code for the &quot;[&quot; instruction<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; is then retrieved from the stack, the correct target value is<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; computed and stored, and then the current instruction's jmp target<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; is computed and emitted.<\/span><br \/>\n<br \/>\nendbracket<span style=\"color: #339933;\">:<\/span> <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #ff0000;\">0x850F313A<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">stosd<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">lea<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #0000ff; font-weight: bold;\">byte<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edi<\/span> <span style=\"color: #339933;\">-<\/span> <span style=\"color: #ff0000;\">8<\/span><span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">pop<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">sub<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">esi<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">sub<\/span> <span style=\"color: #46aa03; font-weight: bold;\">eax<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edi<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">stosd<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jmp<\/span> short relay<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; This is the entry point, for both the compiler and its compiled<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; programs. The shared initialization code sets ecx to the beginning<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; of the array that is the compiled program's data area, and edx to<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; one. (This also clears the zero flag for the relay jump below.) The<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; registers are then saved on the stack, to be restored at the end.<\/span><br \/>\n<br \/>\n_start<span style=\"color: #339933;\">:<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><span style=\"color: #339933;\">,<\/span> DATAORG<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">inc<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">pusha<\/span><br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; At this point, the compiler and its compiled programs diverge.<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; Although every compiled program includes all the code in this file<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; above this point, only the three instructions directly above are<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; actually used by both. This point is where the compiler begins<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; storing the generated code, so only the compiler sees the<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; instructions below. This routine first modifies ecx to contain<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; TEXTORG, which is stored on the stack, and then offsets it to point<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; to filesize. edi is set equal to codebuf, and then the compiler<\/span><br \/>\n<span style=\"color: #666666; font-style: italic;\">;; enters the main loop.<\/span><br \/>\n<br \/>\ncodebuf<span style=\"color: #339933;\">:<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ch<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #009900; font-weight: bold;\">&#40;<\/span>TEXTORG &gt;&gt; <span style=\"color: #ff0000;\">8<\/span><span style=\"color: #009900; font-weight: bold;\">&#41;<\/span> &amp; <span style=\"color: #ff0000;\">0xFF<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">push<\/span>&nbsp; &nbsp; <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">mov<\/span> <span style=\"color: #46aa03; font-weight: bold;\">cl<\/span><span style=\"color: #339933;\">,<\/span> filesize <span style=\"color: #339933;\">-<\/span> <span style=\"color: #0000ff; font-weight: bold;\">$$<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">lea<\/span> <span style=\"color: #46aa03; font-weight: bold;\">edi<\/span><span style=\"color: #339933;\">,<\/span> <span style=\"color: #009900; font-weight: bold;\">&#91;<\/span><span style=\"color: #0000ff; font-weight: bold;\">byte<\/span> <span style=\"color: #46aa03; font-weight: bold;\">ecx<\/span> <span style=\"color: #339933;\">+<\/span> codebuf <span style=\"color: #339933;\">-<\/span> filesize<span style=\"color: #009900; font-weight: bold;\">&#93;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span style=\"color: #00007f; font-weight: bold;\">jmp<\/span> short relay<br \/>\n<br \/>\n<span style=\"color: #666666; font-style: italic;\">;; Here ends the file image.<\/span><br \/>\n<br \/>\ncompilersize&nbsp; &nbsp; <span style=\"color: #0000ff; font-weight: bold;\">equ<\/span> <span style=\"color: #0000ff; font-weight: bold;\">$<\/span> <span style=\"color: #339933;\">-<\/span> <span style=\"color: #0000ff; font-weight: bold;\">$$<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>\u6267\u884c\uff1a<\/p>\n<div class=\"codecolorer-container bash geshi\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/><\/div><\/td><td><div class=\"bash codecolorer\" style=\"white-space:nowrap\"><span style=\"color: #c20cb9; font-weight: bold;\">yum install<\/span> <span style=\"color: #c20cb9; font-weight: bold;\">nasm<\/span> <span style=\"color: #660033;\">-y<\/span><br \/>\n<span style=\"color: #c20cb9; font-weight: bold;\">nasm<\/span> <span style=\"color: #660033;\">-f<\/span> bin <span style=\"color: #660033;\">-o<\/span> bf_compiler bf.asm<br \/>\n<span style=\"color: #c20cb9; font-weight: bold;\">chmod<\/span> +x .<span style=\"color: #000000; font-weight: bold;\">\/<\/span>bf_compiler<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>\u5c06\u4e0a\u9762\u7684BrainFuck\u7a0b\u5e8f\u4fdd\u5b58\u5728brainfuck.bf\u6587\u4ef6\uff0c\u5728SSH\u4e2d\u6267\u884c\uff1a<\/p>\n<div class=\"codecolorer-container bash geshi\" style=\"overflow:auto;white-space:nowrap;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/><\/div><\/td><td><div class=\"bash codecolorer\" style=\"white-space:nowrap\">.<span style=\"color: #000000; font-weight: bold;\">\/<\/span>bf_compiler <span style=\"color: #000000; font-weight: bold;\">&lt;<\/span> brainfuck.bf <span style=\"color: #000000; font-weight: bold;\">&gt;<\/span> brainfuck.cgi<br \/>\n<span style=\"color: #c20cb9; font-weight: bold;\">chmod<\/span> +x .<span style=\"color: #000000; font-weight: bold;\">\/<\/span>brainfuck.cgi<br \/>\n.<span style=\"color: #000000; font-weight: bold;\">\/<\/span>brainfuck.cgi<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>\u5982\u679c\u8fd9\u65f6\u80fd\u591f\u770b\u5230\u6211\u4eec\u4e4b\u524d\u8bf4\u7684\u90a3\u4e24\u884c\u8f93\u51fa\uff0c\u8bf4\u660e\u7f51\u9875\u7f16\u5199\u6210\u529f\u3002\u7136\u540e\uff0c\u5c06\u8fd9\u4e2a\u6587\u4ef6\u590d\u5236\u5230cgi-bin\u4e0b\u9762\uff0c\u901a\u8fc7\u6d4f\u89c8\u5668\u5c31\u53ef\u4ee5\u8bbf\u95ee\u4e86\u3002\u5982\u679c\u51fa\u73b0HTTP 500\u9519\u8bef\uff0c\u8bf7\u67e5\u770bApache\u65e5\u5fd7\u3002<\/p>\n<p>\u6bd5\u7adf\u662f\u4e00\u4e2a\u6bd4\u8f83\u9ebb\u70e6\u7684\u4e8b\u60c5\uff0c\u6211\u5c31\u4e0d\u518d\u7ee7\u7eed\u7528BrainFuck\u505a\u66f4\u591a\u529f\u80fd\u7684\u7f51\u9875\u4e86\u3002\u5927\u5bb6\u6709\u4ec0\u4e48\u95ee\u9898\u53ef\u4ee5\u5728\u4e0b\u9762\u7559\u8a00\u95ee\u6211\u3002<\/p>\n<p>\u672c\u6587\u4f5c\u8005\u4e3a\u9999\u83c7\u80a5\u725b\uff08<a href=\"http:\/\/qing.su\/article\/119.html\" target=\"_blank\">http:\/\/qing.su\/article\/119.html<\/a>\uff09\uff0c\u8f6c\u8f7d\u8bf7\u6ce8\u660e\u539f\u6587\u94fe\u63a5\uff0c\u8c22\u8c22\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4eca\u5929\u82b1\u4e86\u534a\u4e2a\u5c0f\u65f6\u7528BrainFuck\u8bed\u8a00\u7f16\u5199\u4e86\u4e00\u4e2a\u53ea\u6709\u4e00\u884c\u5b57\u7684\u7f51\u9875\uff08\u540c\u6837\u7684\u4e8b\u60c5\u5982\u679c\u7528C\u8bed\u8a00\u5927\u6982\u9700\u8981\u82b15\u5206\u949f\uff0c\u7528PHP\u53ea\u9700\u898120\u79d2\u949f\uff09\uff0c\u5927\u6982\u6ca1\u4eba\u6bd4\u6211\u66f4\u65e0\u804a\u4e86\u5427\u3002\u5730\u5740\u662fhttp:\/\/qing.su\/cgi-bin\/brainfuck.cgi BrainFuck\u662f\u4e16\u754c\u4e0a\u6700\u7cbe\u81f4\u7684\u56fe\u7075\u5b8c\u5907\u7684\u8ba1\u7b97\u673a\u8bed\u8a00\uff08\u5176\u7f16\u8bd1\u5668\u4ec5\u6709240bytes\uff09\u3002\u5b83\u7531\u516b\u4e2a\u5b57\u7b26\u6784\u6210\uff1a+-.,[]\u5206\u522b\u4ee3\u8868\u4e86\u5de6\u53f3\u4f4d\u79fb\u3001\u589e\u51cf\u53d8\u91cf\u3001\u8f93\u51fa\u8f93\u5165\u4ee5\u53ca\u5faa\u73af\u5f00\u95ed\u3002\u5982\u6b64\u6709\u9650\u7684\u5b57\u7b26\u5e93\u51b3\u5b9a\u4e86\u5176\u7f16\u5199\u8fc7\u7a0b\u7684\u7e41\u7410\u548c\u5197\u957f\u3001\u6613\u8bfb\u6027\u6781\u5dee\uff0c\u51e0\u4e4e\u65e0\u6cd5\u6210\u4e3a\u771f\u6b63\u751f\u4ea7\u4f7f\u7528\u7684\u8ba1\u7b97\u673a\u8bed\u8a00\u3002\u6216\u8bb8\uff0c\u5076\u5c14\u7f16\u5199\u4e00\u4e2aBrainFuck\u7a0b\u5e8f\u70e7\u4e00\u70e7\u8111\u5b50\u662f\u4e0d\u9519\u7684\u9009\u62e9\u3002\u4e0b\u9762\u4ecb\u7ecd\u4e00\u4e0b\u7528BrainFuck\u8bed\u8a00\u7f16\u5199\u7f51\u9875\u7684\u65b9\u5f0f\u3002<\/p>\n","protected":false},"author":1,"featured_media":941,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"","_seopress_titles_desc":"","_seopress_robots_index":"","footnotes":""},"categories":[9],"tags":[152,107],"class_list":["post-938","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripts","tag-brainfuck","tag-cgi_program","no-featured-image-padding"],"_links":{"self":[{"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/posts\/938","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/comments?post=938"}],"version-history":[{"count":0,"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/posts\/938\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/media\/941"}],"wp:attachment":[{"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/media?parent=938"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/categories?post=938"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qing.su\/wp-json\/wp\/v2\/tags?post=938"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}