<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=CompilerDev%2FImplementing_Conditional_Statements_And_Loops</id>
	<title>CompilerDev/Implementing Conditional Statements And Loops - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=CompilerDev%2FImplementing_Conditional_Statements_And_Loops"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;action=history"/>
	<updated>2026-04-04T19:17:04Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;diff=945&amp;oldid=prev</id>
		<title>2022年3月19日 (六) 03:44 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;diff=945&amp;oldid=prev"/>
		<updated>2022-03-19T03:44:16Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年3月19日 (六) 03:44的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l93&quot;&gt;第93行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第93行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==== 复合布尔条件 ====&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==== 复合布尔条件 ====&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;对于复合条件，例如逻辑和或逻辑或，简单直接的实现是首先执行测试，然后使用逻辑连字来产生可测试的结果。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;对于复合条件，例如逻辑与（AND）或逻辑或（OR），简单直接的实现是首先执行测试，然后使用逻辑连字来产生可测试的结果。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (!(a &amp;lt;= b &amp;amp;&amp;amp; b &amp;lt; c))&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (!(a &amp;lt;= b &amp;amp;&amp;amp; b &amp;lt; c))&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l164&quot;&gt;第164行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第164行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;同样，对于嵌套的 '''if''，其中内部 '''if''' 是外部循环的第一个或最后一个子句，则它可以删除无关的标签:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;同样，对于嵌套的 '''if&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;'&lt;/ins&gt;''，其中内部 '''if''' 是外部循环的第一个或最后一个子句，则它可以删除无关的标签:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{|&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{|&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l197&quot;&gt;第197行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第197行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;对于这些简单的情况，由于给定运算符到其逆的映射是固定的 (例如，要实现 “小于”，总是会替换为 “大于或等于”)，因此唯一需要的更改是测试的代码从逆条件中发出。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;对于这些简单的情况，由于给定运算符到其逆的映射是固定的 (例如，要实现 “小于”，总是会替换为 “大于或等于”)，因此唯一需要的更改是测试的代码从逆条件中发出。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;优化复合条件有点棘手，因为您需要考虑哪些操作会反转哪些其他操作，以及如何应用诸如”德·摩根定理“（或称为反演律）之类的方法。 &lt;/del&gt;但是，对于大多数编译器来说，执行某些消除仍然是合理的，例如用短路分支代替单独的测试。 在'''AND'''的情况下，可以通过将第一个测试短路到有条件的'''AND'''部分的末尾来开始，以便仅在第一个测试为真的情况下才检查第二个测试。 对于'''NOT'''，只需将最终情况''not''反转即可获得正确的结果:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;优化复合条件有点棘手，因为你需要考虑哪些操作会反转哪些其他操作，以及如何应用诸如”德·摩根定理“（或称为反演律）之类的方法。 &lt;/ins&gt;但是，对于大多数编译器来说，执行某些消除仍然是合理的，例如用短路分支代替单独的测试。 在'''AND'''的情况下，可以通过将第一个测试短路到有条件的'''AND'''部分的末尾来开始，以便仅在第一个测试为真的情况下才检查第二个测试。 对于'''NOT'''，只需将最终情况''not''反转即可获得正确的结果:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;尽管麻烦，但如果我们保留一个布尔函数及其逆的表，并且愿意对操作顺序进行简单的分析，那么稍加努力，可能会有更好的解决方案。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;尽管麻烦，但如果我们保留一个布尔函数及其逆的表，并且愿意对操作顺序进行简单的分析，那么稍加努力，可能会有更好的解决方案。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;diff=941&amp;oldid=prev</id>
		<title>2022年3月19日 (六) 01:00 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;diff=941&amp;oldid=prev"/>
		<updated>2022-03-19T01:00:57Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年3月19日 (六) 01:00的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= 一般概念 =&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;= 一般概念 =&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;对于传统的指令集体系结构，例如x86，ARM，8051，MIPS或目前广泛使用的大多数其他CPU类型 (&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2016&lt;/del&gt;)，条件语句 (例如 '''if' ''/'''elsif'''/'''else''')，以及循环构造 (例如 '''for''' 或 '''while''')，通常是通过组合测试来实现的，条件跳跃/分支 (jz，beq等) 和无条件分支 (jmp，bra，j等)。 虽然某些常见的ISA(指令集架构)具有用于重复或循环的专用指令 (例如x86上的 ''rep''' 和 '''LOOP''' 指令)，但由于增加了需要确定它们可用的工作，因此很少有编译器使用它们。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;对于传统的指令集体系结构，例如x86，ARM，8051，MIPS或目前广泛使用的大多数其他CPU类型 (&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;2016年&lt;/ins&gt;)，条件语句 (例如 '''if'''/'''elsif'''/'''else''')，以及循环构造 (例如 '''for''' 或 '''while''')，通常是通过组合测试来实现的，条件跳跃/分支 (jz，beq等) 和无条件分支 (jmp，bra，j等)。 虽然某些常见的ISA(指令集架构)具有用于重复或循环的专用指令 (例如x86上的 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;'&lt;/ins&gt;''rep''' 和 '''LOOP''' 指令)，但由于增加了需要确定它们可用的工作，因此很少有编译器使用它们。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;下面给出了 [https://en.wikipedia.org/wiki/X86_assembly_language Intel x86-64] 、 [[ARM Overview|ARM]] 和 [https://en.wikipedia.org/wiki/MIPS_instruction_set MIPS R2000汇编语言] 指令集的示例。 这里假设编译器先产生汇编语言; 对于直接生成 [[Executable Formats|可执行文件]] 的编译器，必须处理将由汇编程序完成的内部处理 (例如，跟踪分支目标)。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;下面给出了 [https://en.wikipedia.org/wiki/X86_assembly_language Intel x86-64]、[[ARM Overview|ARM]]和[https://en.wikipedia.org/wiki/MIPS_instruction_set MIPS R2000汇编语言] 指令集的示例。 这里假设编译器先产生汇编语言; 对于直接生成 [[Executable Formats|可执行文件]] 的编译器，必须处理将由汇编程序完成的内部处理 (例如，跟踪分支目标)。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 一般条件语句 ==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;== 一般条件语句 ==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l45&quot;&gt;第45行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第45行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;请注意，编译器必须为每个分支目标生成唯一的标签或目标表列表; 最简单的实现是保留标签的计数，并为它们分配一个单独的标签名称，并附加计数。(译者注：这里main.if0.&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;true,main.if0.true这样的汇编定位标签&lt;/del&gt;) 为了可读性，示例代码使用带有函数名称 (在本例中为main)，表达式类型以及该类型表达式的计数的本地标签。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;请注意，编译器必须为每个分支目标生成唯一的标签或目标表列表; 最简单的实现是保留标签的计数，并为它们分配一个单独的标签名称，并附加计数。(译者注：这里main.if0.&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;true就是这样的汇编定位标签&lt;/ins&gt;) 为了可读性，示例代码使用带有函数名称 (在本例中为main)，表达式类型以及该类型表达式的计数的本地标签。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;因此，对于嵌套的 ''if'，例如&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;因此，对于嵌套的 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;'&lt;/ins&gt;''if&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;''&lt;/ins&gt;'，例如&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (a == b)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (a == b)&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l197&quot;&gt;第197行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第197行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;对于这些简单的情况，由于给定运算符到其逆的映射是固定的 (例如，要实现 “小于”，总是会替换为 “大于或等于”)，因此唯一需要的更改是测试的代码从逆条件中发出。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;对于这些简单的情况，由于给定运算符到其逆的映射是固定的 (例如，要实现 “小于”，总是会替换为 “大于或等于”)，因此唯一需要的更改是测试的代码从逆条件中发出。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;优化复合条件有点棘手，因为您需要考虑哪些操作会反转哪些其他操作，以及如何应用诸如”德·摩根定理“（或称为反演律）之类的方法。 但是，对于大多数编译器来说，执行某些消除仍然是合理的，例如用短路分支代替单独的测试。 在 '''AND''' 的情况下，可以通过将第一个测试短路到有条件的 '''AND''' 部分的末尾来开始，以便仅在第一个测试为真的情况下才检查第二个测试。 对于 '''NOT' ''&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;，只需将最终情况“ &lt;/del&gt;not &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;”反转即可获得正确的结果&lt;/del&gt;:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;优化复合条件有点棘手，因为您需要考虑哪些操作会反转哪些其他操作，以及如何应用诸如”德·摩根定理“（或称为反演律）之类的方法。 但是，对于大多数编译器来说，执行某些消除仍然是合理的，例如用短路分支代替单独的测试。 在'''AND'''的情况下，可以通过将第一个测试短路到有条件的'''AND'''部分的末尾来开始，以便仅在第一个测试为真的情况下才检查第二个测试。 对于'''NOT'''&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;，只需将最终情况''&lt;/ins&gt;not&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;''反转即可获得正确的结果&lt;/ins&gt;:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;尽管麻烦，但如果我们保留一个布尔函数及其逆的表，并且愿意对操作顺序进行简单的分析，那么稍加努力，可能会有更好的解决方案。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;尽管麻烦，但如果我们保留一个布尔函数及其逆的表，并且愿意对操作顺序进行简单的分析，那么稍加努力，可能会有更好的解决方案。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l244&quot;&gt;第244行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第244行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;然而，即使是简易的编译器，通常也会通过使用无条件分支来进行「循环反转」，然后是循环标签，然后是主体，然后将循环条件作为原始无条件分支的目标，条件倒置&lt;/del&gt;:&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;然而，即使是简易的编译器，通常也会通过使用无条件分支来进行''循环反转（loop inversion）''，然后是循环标签，然后是主体，然后将循环条件作为原始无条件分支的目标，条件倒置&lt;/ins&gt;:&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{|&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{|&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l268&quot;&gt;第268行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第268行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;这意味着在循环进入之后，循环只有无条件分支，使其更快。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;对于手动编码的递归下降编译器，这仅是更改解析发射函数的调用顺序的问题。&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;这意味着在循环进入之后，循环只有无条件分支，使其更快。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;对于手动编码的递归下降编译器，这仅是更改解析发射（parsing-emitting）函数的调用顺序的问题。&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;diff=399&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“= 一般概念 = 对于传统的指令集体系结构，例如x86，ARM，8051，MIPS或目前广泛使用的大多数其他CPU类型 (2016)，条件语句 (例如 '''if' ''/'''elsif'''/'''else''')，以及循环构造 (例如 '''for''' 或 '''while''')，通常是通过组合测试来实现的，条件跳跃/分支 (jz，beq等) 和无条件分支 (jmp，bra，j等)。 虽然某些常见的ISA(指令集架构)具有用于重复或循环的专用指令 (例如x…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=CompilerDev/Implementing_Conditional_Statements_And_Loops&amp;diff=399&amp;oldid=prev"/>
		<updated>2022-02-08T08:43:25Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“= 一般概念 = 对于传统的指令集体系结构，例如x86，ARM，8051，MIPS或目前广泛使用的大多数其他CPU类型 (2016)，条件语句 (例如 &amp;#039;&amp;#039;&amp;#039;if&amp;#039; &amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039;elsif&amp;#039;&amp;#039;&amp;#039;/&amp;#039;&amp;#039;&amp;#039;else&amp;#039;&amp;#039;&amp;#039;)，以及循环构造 (例如 &amp;#039;&amp;#039;&amp;#039;for&amp;#039;&amp;#039;&amp;#039; 或 &amp;#039;&amp;#039;&amp;#039;while&amp;#039;&amp;#039;&amp;#039;)，通常是通过组合测试来实现的，条件跳跃/分支 (jz，beq等) 和无条件分支 (jmp，bra，j等)。 虽然某些常见的ISA(指令集架构)具有用于重复或循环的专用指令 (例如x…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= 一般概念 =&lt;br /&gt;
对于传统的指令集体系结构，例如x86，ARM，8051，MIPS或目前广泛使用的大多数其他CPU类型 (2016)，条件语句 (例如 '''if' ''/'''elsif'''/'''else''')，以及循环构造 (例如 '''for''' 或 '''while''')，通常是通过组合测试来实现的，条件跳跃/分支 (jz，beq等) 和无条件分支 (jmp，bra，j等)。 虽然某些常见的ISA(指令集架构)具有用于重复或循环的专用指令 (例如x86上的 ''rep''' 和 '''LOOP''' 指令)，但由于增加了需要确定它们可用的工作，因此很少有编译器使用它们。&lt;br /&gt;
&lt;br /&gt;
下面给出了 [https://en.wikipedia.org/wiki/X86_assembly_language Intel x86-64] 、 [[ARM Overview|ARM]] 和 [https://en.wikipedia.org/wiki/MIPS_instruction_set MIPS R2000汇编语言] 指令集的示例。 这里假设编译器先产生汇编语言; 对于直接生成 [[Executable Formats|可执行文件]] 的编译器，必须处理将由汇编程序完成的内部处理 (例如，跟踪分支目标)。&lt;br /&gt;
&lt;br /&gt;
== 一般条件语句 ==&lt;br /&gt;
=== If ===&lt;br /&gt;
基本的 '''if''' 语句的直接实现通常由判断条件和为true时的代码条件分支(称为''consequent'')组成，在之后是无条件结尾分支:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (a == b)&lt;br /&gt;
{&lt;br /&gt;
    /* do something */&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
生成的代码 (假设 '''a''' 和 '''b''' 已经在适当的寄存器中) 可能看起来像:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    cmp rax, rbx&lt;br /&gt;
    je main.if0.true&lt;br /&gt;
    jmp main.if0.end&lt;br /&gt;
main.if0.true:&lt;br /&gt;
    ;;; consequent&lt;br /&gt;
main.if0.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    teq r0, r1&lt;br /&gt;
    beq main.if0.true&lt;br /&gt;
    b main.if0.end&lt;br /&gt;
main.if0.true:&lt;br /&gt;
    ;;; consequent&lt;br /&gt;
main.if0.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    beq $t0, $t1, main.if0.true&lt;br /&gt;
    j main.if0.end&lt;br /&gt;
main.if0.true:&lt;br /&gt;
    ### consequent&lt;br /&gt;
main.if0.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
请注意，编译器必须为每个分支目标生成唯一的标签或目标表列表; 最简单的实现是保留标签的计数，并为它们分配一个单独的标签名称，并附加计数。(译者注：这里main.if0.true,main.if0.true这样的汇编定位标签) 为了可读性，示例代码使用带有函数名称 (在本例中为main)，表达式类型以及该类型表达式的计数的本地标签。&lt;br /&gt;
&lt;br /&gt;
因此，对于嵌套的 ''if'，例如&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (a == b)&lt;br /&gt;
{&lt;br /&gt;
    if (b &amp;lt;= c)&lt;br /&gt;
    {&lt;br /&gt;
        /* do the inner clause */&lt;br /&gt;
    }&lt;br /&gt;
    /* do the rest of the outer clause */&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
它可能产生:&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;    cmp rax, rbx&lt;br /&gt;
    je main.if1.true&lt;br /&gt;
    jmp main.if1.end&lt;br /&gt;
main.if1.true:&lt;br /&gt;
    cmp rbx, rcx&lt;br /&gt;
    jle main.if2.true&lt;br /&gt;
    jmp main.if2.end&lt;br /&gt;
main.if2.true:&lt;br /&gt;
    ;;; do the inner clause&lt;br /&gt;
main.if2.end:&lt;br /&gt;
    ;;; do the rest of the outer clause&lt;br /&gt;
main.if1.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;    bge $t0, $t1, main.if1.true&lt;br /&gt;
    j main.if1.end&lt;br /&gt;
main.if2.true:&lt;br /&gt;
    blt $t0, $t2, main.if2.true&lt;br /&gt;
    j main.if2.end&lt;br /&gt;
main.if2.true:&lt;br /&gt;
    ;;; consequent for inner conditional&lt;br /&gt;
main.if2.end:&lt;br /&gt;
    ;;; remaining code&lt;br /&gt;
main.if1.end:&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 复合布尔条件 ====&lt;br /&gt;
对于复合条件，例如逻辑和或逻辑或，简单直接的实现是首先执行测试，然后使用逻辑连字来产生可测试的结果。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;if (!(a &amp;lt;= b &amp;amp;&amp;amp; b &amp;lt; c))&lt;br /&gt;
    /* do something */&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
它可以简单地产生&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    ble $t0, $t1, main.if3.and0.left.true&lt;br /&gt;
    clear $t3&lt;br /&gt;
    j main.if3.and0.right&lt;br /&gt;
main.if3.and0.left.true:&lt;br /&gt;
    move $t3, 1&lt;br /&gt;
    j main.if3.and0.right&lt;br /&gt;
main.if3.and0.right:&lt;br /&gt;
    ble $t0, $t1, main.if3.and0.right.true&lt;br /&gt;
    clear $t3&lt;br /&gt;
    j main.if3.and0.test&lt;br /&gt;
main.if3.and0.right.true:&lt;br /&gt;
    move $t3, 1&lt;br /&gt;
    j main.if3.and0.test&lt;br /&gt;
main.if3.and0.test:&lt;br /&gt;
    and $t3, $t3, $t4&lt;br /&gt;
    not $t5, $t3&lt;br /&gt;
    bnez $t5, main.if3.true&lt;br /&gt;
    j main.if3.end&lt;br /&gt;
main.if3.true:&lt;br /&gt;
    ;;; consequent&lt;br /&gt;
main.if3.end:&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
虽然这是条件的字面翻译，但显然不是最佳的。&lt;br /&gt;
&lt;br /&gt;
==== 基本优化 ====&lt;br /&gt;
&lt;br /&gt;
一个明显的，合理简单的优化是否定或反转条件，从而消除了对无条件分支的需求:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    cmp rax, rbx&lt;br /&gt;
    jne main.if0.end&lt;br /&gt;
    ;;; consequent&lt;br /&gt;
main.if0.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    teq r0, r1&lt;br /&gt;
    bne main.if0.end&lt;br /&gt;
    ;;; consequent&lt;br /&gt;
main.if0.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    bne $t0, $t1, main.if4.end&lt;br /&gt;
    ;;; consequent&lt;br /&gt;
main.if4.end:&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
同样，对于嵌套的 '''if''，其中内部 '''if''' 是外部循环的第一个或最后一个子句，则它可以删除无关的标签:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    cmp rax, rbx&lt;br /&gt;
    jne main.if1.end&lt;br /&gt;
    ;;; if(rax == rbx)&lt;br /&gt;
      cmp rbx, rcx&lt;br /&gt;
      jg main.if2.end&lt;br /&gt;
      ;;; if(rbx &amp;lt;= rcx)&lt;br /&gt;
      ;;; do the inner clause&lt;br /&gt;
main.if2.end:&lt;br /&gt;
    ;;; do the rest of the outer clause&lt;br /&gt;
main.if1.end:&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
    blt $t0, $t1, main.if5.end&lt;br /&gt;
    bge $t0, $t2, main.if6.end&lt;br /&gt;
    ;;; inner consequent&lt;br /&gt;
main.if6.end:&lt;br /&gt;
    ;;; remaining code of outer consequent&lt;br /&gt;
main.if2.end:&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
对于这些简单的情况，由于给定运算符到其逆的映射是固定的 (例如，要实现 “小于”，总是会替换为 “大于或等于”)，因此唯一需要的更改是测试的代码从逆条件中发出。&lt;br /&gt;
&lt;br /&gt;
优化复合条件有点棘手，因为您需要考虑哪些操作会反转哪些其他操作，以及如何应用诸如”德·摩根定理“（或称为反演律）之类的方法。 但是，对于大多数编译器来说，执行某些消除仍然是合理的，例如用短路分支代替单独的测试。 在 '''AND''' 的情况下，可以通过将第一个测试短路到有条件的 '''AND''' 部分的末尾来开始，以便仅在第一个测试为真的情况下才检查第二个测试。 对于 '''NOT' ''，只需将最终情况“ not ”反转即可获得正确的结果:&lt;br /&gt;
&lt;br /&gt;
尽管麻烦，但如果我们保留一个布尔函数及其逆的表，并且愿意对操作顺序进行简单的分析，那么稍加努力，可能会有更好的解决方案。&lt;br /&gt;
&lt;br /&gt;
== 定义循环 ==&lt;br /&gt;
确定循环的直接简单实现是在循环开始时的条件分支，在循环结束时的无条件分支回到该条件分支，这也是显式for循环的简单实现。 MIPS汇编代码中的一个示例 (使用伪指令) 可能是:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
        xor rcx, rcx&lt;br /&gt;
        mov rbx, for_loop_count&lt;br /&gt;
for0.start:&lt;br /&gt;
        ; if rcx is greater than or equal&lt;br /&gt;
        ; to rbx, jump past the loop&lt;br /&gt;
        cmp rcx, rbx&lt;br /&gt;
        jge for1.end&lt;br /&gt;
        ;;  body of the loop here&lt;br /&gt;
        inc rcx&lt;br /&gt;
        jmp for0.start&lt;br /&gt;
for0.end:&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;        mov r0, #0&lt;br /&gt;
        mov r1, #for_loop_count&lt;br /&gt;
for0.start:&lt;br /&gt;
        ; if r1 is greater than or equal&lt;br /&gt;
        ; to r0, jump past the loop&lt;br /&gt;
        cmp r0, r1&lt;br /&gt;
        bge for1.end&lt;br /&gt;
        ;;  body of the loop here&lt;br /&gt;
        add r0, r0, #1&lt;br /&gt;
        b for0.start&lt;br /&gt;
for0.end:&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;        clear $t0&lt;br /&gt;
        move $t1, for_loop_count&lt;br /&gt;
for0.start:&lt;br /&gt;
        ; if t1 is greater than or equal&lt;br /&gt;
        ; to t0, jump past the loop&lt;br /&gt;
        bge $t0, $t1, for1.end&lt;br /&gt;
        ;;  body of the loop here&lt;br /&gt;
        addi $t0, $t0, 1&lt;br /&gt;
        bra for0.start&lt;br /&gt;
for0.end&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
然而，即使是简易的编译器，通常也会通过使用无条件分支来进行「循环反转」，然后是循环标签，然后是主体，然后将循环条件作为原始无条件分支的目标，条件倒置:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! x86-64&lt;br /&gt;
! ARM&lt;br /&gt;
! MIPS&lt;br /&gt;
|+&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
|&amp;lt;pre&amp;gt;   clear $t0&lt;br /&gt;
        move $t1, for_loop_count&lt;br /&gt;
        bra for1.test&lt;br /&gt;
for1.start:&lt;br /&gt;
        ;;  body of the loop here&lt;br /&gt;
        addi $t0, $t0, 1&lt;br /&gt;
for1.test:&lt;br /&gt;
        ; if t1 is less than to t0,&lt;br /&gt;
        ; jump past the loop&lt;br /&gt;
        blt $t0, $t1, for1.start&lt;br /&gt;
for1.end&amp;lt;/pre&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
这意味着在循环进入之后，循环只有无条件分支，使其更快。 对于手动编码的递归下降编译器，这仅是更改解析发射函数的调用顺序的问题。&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>