<?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=Inline_Assembly</id>
	<title>Inline Assembly - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=Inline_Assembly"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;action=history"/>
	<updated>2026-04-04T19:38:03Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=678&amp;oldid=prev</id>
		<title>2022年2月22日 (二) 15:49 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=678&amp;oldid=prev"/>
		<updated>2022-02-22T15:49:40Z</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年2月22日 (二) 15:49的版本&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-l24&quot;&gt;第24行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第24行：&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&amp;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;&amp;lt;/source&amp;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;现在，你可能想知道为什么这%%会出现。 这是因为内联汇编的一个有趣特性：你可以在汇编代码中使用一些C变量。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;因为，为了简化该机制的实现，GCC在汇编代码中命名这些变量&lt;/del&gt;%0、%1等等，从输入/输出operand部分中提到的第一个变量开始。 你需要使用此%%语法来帮助GCC区分寄存器和参数。&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;现在，你可能想知道为什么这%%会出现。 这是因为内联汇编的一个有趣特性：你可以在汇编代码中使用一些C变量。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;为了简化该机制的实现，GCC在汇编代码中命名这些变量&lt;/ins&gt;%0、%1等等，从输入/输出operand部分中提到的第一个变量开始。 你需要使用此%%语法来帮助GCC区分寄存器和参数。&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-l32&quot;&gt;第32行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第32行：&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;asm (&amp;quot;movl %1, %%eax;  &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;asm (&amp;quot;movl %1, %%eax;  &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;div&gt;       movl %%eax, %0;&amp;quot;&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;       movl %%eax, %0;&amp;quot;&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;      :&amp;quot;=r&amp;quot;(b)        /* &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;output &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;      :&amp;quot;=r&amp;quot;(b)        /*&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; 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;      :&amp;quot;r&amp;quot;(a)         /* &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;input &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;      :&amp;quot;r&amp;quot;(a)         /*&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; 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;      :&amp;quot;%eax&amp;quot;         /* clobbered register */&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;      :&amp;quot;%eax&amp;quot;         /* &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;被破坏的寄存器(&lt;/ins&gt;clobbered register&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;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;div&gt;&amp;lt;/source&amp;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;&amp;lt;/source&amp;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-l40&quot;&gt;第40行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第40行：&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;这里你已经设法使用汇编代码将“a”的值复制到“b”中，在汇编代码中有效地使用了一些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;这里你已经设法使用汇编代码将“a”的值复制到“b”中，在汇编代码中有效地使用了一些C变量。&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;最后一个“clobbered register”部分用于告诉GCC你的代码正在使用处理器的一些寄存器，并且在执行asm代码段之前，它应该将正在运行的程序中的所有活动数据移出该寄存器。 在上面的例子中，我们在第一条指令中将&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;移动到eax，有效地擦除了它的内容，因此我们需要要求GCC在操作之前从未保存的数据中清除该寄存器。&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;最后一个“clobbered register”部分用于告诉GCC你的代码正在使用处理器的一些寄存器，并且在执行asm代码段之前，它应该将正在运行的程序中的所有活动数据移出该寄存器。 在上面的例子中，我们在第一条指令中将&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;移动到eax，有效地擦除了它的内容，因此我们需要要求GCC在操作之前清除该寄存器，所以要保存寄存器数据。&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-l52&quot;&gt;第52行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第52行：&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;=== 输出Operands ===&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;=== 输出Operands ===&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;本节“输出Operands”部分用于告诉编译器/汇编程序如何处理存储ASM代码输出的C变量。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;输出Operands是一组Pairs，每个Operands由一个字符串文字组成，称为“constraint”，说明C变量应该映射到哪里（寄存器通常用于最佳性能），以及要映射到哪里的C变量（在括号中）。&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;本节“输出Operands”部分用于告诉编译器/汇编程序如何处理存储ASM代码输出的C变量。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;输出Operands是一组各自成对，每个Operands由一个字符串文字组成，称为“constraint”，说明C变量应该映射到哪里（到寄存器通常用于最佳性能），以及要映射到哪里的C变量（在括号中）。&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;假设你正在为IA32体系结构编码，在constraint中，“a”表示EAX，“b”表示EBX，“c”表示ECX，“d”表示EDX，“S”表示ESI，“d”表示EDI（请阅读GCC手册中的完整列表）。 等式符号表示汇编代码不关心映射变量的初始值（这允许一些优化）。 考虑到所有这些，现在下面的代码将EAX设置为0就很清楚了。&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;假设你正在为IA32体系结构编码，在constraint中，“a”表示EAX，“b”表示EBX，“c”表示ECX，“d”表示EDX，“S”表示ESI，“d”表示EDI（请阅读GCC手册中的完整列表）。 等式符号表示汇编代码不关心映射变量的初始值（这允许一些优化）。 考虑到所有这些，现在下面的代码将EAX设置为0就很清楚了。&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-l77&quot;&gt;第77行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第77行：&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;=== 输入Operands ===&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;=== 输入Operands ===&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;虽然输出Operands通常只用于输出，输入操作数还允许参数化ASM代码； &lt;/del&gt;将只读参数从C代码传递到ASM块。 同样，字符串文字用于指定详细信息。&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;虽然输出Operands通常只用于输出，输入Operands还允许参数化ASM代码； &lt;/ins&gt;将只读参数从C代码传递到ASM块。 同样，字符串文字用于指定详细信息。&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;如果你想将某个值移动到EAX，可以通过以下方式执行（即使这样做，而不是直接将该值映射到EAX肯定是毫无用处的）：&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;如果你想将某个值移动到EAX，可以通过以下方式执行（即使这样做，而不是直接将该值映射到EAX肯定是毫无用处的）：&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-l92&quot;&gt;第92行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第92行：&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;请注意，GCC将始终假定输入Operands是只读的（不更改的）。 写入输入Operands时，正确的做法是将它们列为输出，但不使用等式符号，因为这一次它们的原始值很重要。 下面是一个简单的例子：&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;请注意，GCC将始终假定输入Operands是只读的（不更改的）。 写入输入Operands时，正确的做法是将它们列为输出，但不使用等式符号，因为这一次它们的原始值很重要。 下面是一个简单的例子：&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;div&gt;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;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;&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;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;asm(&amp;quot;mov %%eax,%%ebx&amp;quot;: : &amp;quot;a&amp;quot; (amount));//&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;useless but it gets the idea&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;asm(&amp;quot;mov %%eax,%%ebx&amp;quot;: : &amp;quot;a&amp;quot; (amount));// &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;div&gt;&amp;lt;/source&amp;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;&amp;lt;/source&amp;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;div&gt;Eax将包含“amount”，并移动到ebx中。&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;Eax将包含“amount”，并移动到ebx中。&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 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;请记住一件事很重要：“C/C++编译器对汇编器一无所知”。 对于编译器来说，asm语句是不透明的，如果你没有指定任何输出，它甚至可能得出结论，认为这是一个不可操作的语句，并对其进行优化。 一些第三方文档指出，使用asm &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;volatile将导致关键字不被移动。 &lt;/del&gt;然而，根据GCC文档，“volatile关键字表示指令有重要的副作用。 如果可以访问易失性asm，GCC将不会删除该asm。''，这只表示它不会被删除 （也就是说，它是否仍然可以移动是一个尚未回答的问题）。 一种可行的方法是使用asm（volatile）并将“内存”放入缓冲寄存器中，如下所示：&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;请记住一件事很重要：“C/C++编译器对汇编器一无所知”。 对于编译器来说，asm语句是不透明的，如果你没有指定任何输出，它甚至可能得出结论，认为这是一个不可操作的语句，并对其进行优化。 一些第三方文档指出，使用asm &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;volatile将导致不被移动的关键字。 &lt;/ins&gt;然而，根据GCC文档，“volatile关键字表示指令有重要的副作用。 如果可以访问易失性asm，GCC将不会删除该asm。''，这只表示它不会被删除 （也就是说，它是否仍然可以移动是一个尚未回答的问题）。 一种可行的方法是使用asm（volatile）并将“内存”放入缓冲寄存器中，如下所示：&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;&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;&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-l108&quot;&gt;第108行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第108行：&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;Clobbered Registers列表是一个以逗号分隔的寄存器名列表，以字符串文本形式显示。&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;Clobbered Registers列表是一个以逗号分隔的寄存器名列表，以字符串文本形式显示。&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;通配符（Wildcards）：如何让编译器选择 &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;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 colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l125&quot;&gt;第125行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第125行：&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;| 说明值 '0x21' 可以在out或in操作中用作常数，范围从0到255&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;| 说明值 '0x21' 可以在out或in操作中用作常数，范围从0到255&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;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;当然，你可以对operand选择施加更多constraints，无论是否依赖于机器，这些constraints都列在GCC的手册中 (参考[http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Simple-Constraints.html#Simple-Constraints], [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Modifiers.html#Modifiers], [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Multi_002dAlternative.html#Multi_002dAlternative], &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;and &lt;/del&gt;[http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Machine-Constraints.html#Machine-Constraints])&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;当然，你可以对operand选择施加更多constraints，无论是否依赖于机器，这些constraints都列在GCC的手册中 (参考[http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Simple-Constraints.html#Simple-Constraints], [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Modifiers.html#Modifiers], [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Multi_002dAlternative.html#Multi_002dAlternative], &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;和&lt;/ins&gt;[http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Machine-Constraints.html#Machine-Constraints])&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;== 使用C99 ==&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;== 使用C99 ==&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=Inline_Assembly&amp;diff=666&amp;oldid=prev</id>
		<title>2022年2月22日 (二) 02:32 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=666&amp;oldid=prev"/>
		<updated>2022-02-22T02:32:41Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;amp;diff=666&amp;amp;oldid=665&quot;&gt;显示更改&lt;/a&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=665&amp;oldid=prev</id>
		<title>2022年2月22日 (二) 02:23 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=665&amp;oldid=prev"/>
		<updated>2022-02-22T02:23:51Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;amp;diff=665&amp;amp;oldid=68&quot;&gt;显示更改&lt;/a&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=68&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为““内联汇编”背后的思想是在除了使用Assembly语言之外别无选择的情况下，使用&lt;tt&gt;asm&lt;/tt&gt;关键字在C/C++代码中嵌入汇编指令。  == 概述 == 有时，即使C/C++是您选择的语言，您“需要”在操作系统中使用一些汇编代码。 无论是因为极端的优化需求，还是因为您正在实现的代码是高度特定于硬件的（比如说，通过端口输出数据），结果都是一样的：没有…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=Inline_Assembly&amp;diff=68&amp;oldid=prev"/>
		<updated>2021-12-23T02:26:40Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为““内联汇编”背后的思想是在除了使用&lt;a href=&quot;/index.php?title=Assembly&quot; title=&quot;Assembly&quot;&gt;Assembly&lt;/a&gt;语言之外别无选择的情况下，使用&amp;lt;tt&amp;gt;asm&amp;lt;/tt&amp;gt;关键字在C/C++代码中嵌入汇编指令。  == 概述 == 有时，即使C/C++是您选择的语言，您“需要”在操作系统中使用一些汇编代码。 无论是因为极端的优化需求，还是因为您正在实现的代码是高度特定于硬件的（比如说，通过端口输出数据），结果都是一样的：没有…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;“内联汇编”背后的思想是在除了使用[[Assembly]]语言之外别无选择的情况下，使用&amp;lt;tt&amp;gt;asm&amp;lt;/tt&amp;gt;关键字在C/C++代码中嵌入汇编指令。&lt;br /&gt;
&lt;br /&gt;
== 概述 ==&lt;br /&gt;
有时，即使C/C++是您选择的语言，您“需要”在操作系统中使用一些汇编代码。 无论是因为极端的优化需求，还是因为您正在实现的代码是高度特定于硬件的（比如说，通过端口输出数据），结果都是一样的：没有办法绕过它。 必须使用汇编语言。&lt;br /&gt;
&lt;br /&gt;
您可以选择编写一个汇编函数并调用它，但是有时甚至“调用”开销对您来说都太大了。 在这种情况下，您需要的是内联程序集，这意味着使用&amp;lt;TT&amp;gt; ASM*（）/TT&amp;gt;关键字插入代码中间的任意程序集片段。 这个关键字的工作方式是特定于编译器的。 本文描述了它在GCC中的工作方式，因为它是操作系统世界中使用最多的编译器。&lt;br /&gt;
&lt;br /&gt;
== 语法 ==&lt;br /&gt;
这是在C/C++代码中使用&amp;lt;tt&amp;gt;asm（）&amp;lt;/tt&amp;gt;关键字的语法：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm ( assembler template&lt;br /&gt;
    : output operands                   (optional)&lt;br /&gt;
    : input operands                    (optional)&lt;br /&gt;
    : clobbered registers list          (optional)&lt;br /&gt;
    );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
汇编程序模板基本上是[[GAS]]兼容的代码，除非有限制，在这种情况下，寄存器名必须以%%而不是%开头。 这意味着以下两行代码都将&amp;lt;tt&amp;gt;eax&amp;lt;/tt&amp;gt;寄存器的内容移动到&amp;lt;tt&amp;gt;ebx&amp;lt;/tt&amp;gt;：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm (&amp;quot;movl %eax, %ebx&amp;quot;);&lt;br /&gt;
asm (&amp;quot;movl %%eax, %%ebx&amp;quot; : );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
现在，您可能想知道为什么这%%会出现。 这就是内联汇编的一个有趣特性：您可以在汇编代码中使用一些C变量。 因为，为了简化该机制的实现，GCC在汇编代码中命名这些变量%0、%1等等，从输入/输出操作数部分中提到的第一个变量开始。 您需要使用此%%语法来帮助GCC区分寄存器和参数。&lt;br /&gt;
&lt;br /&gt;
操作数的具体工作原理将在后面的章节中详细解释。 现在，如果你写了这样的东西，就足以说明：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int a=10, b;&lt;br /&gt;
asm (&amp;quot;movl %1, %%eax; &lt;br /&gt;
      movl %%eax, %0;&amp;quot;&lt;br /&gt;
     :&amp;quot;=r&amp;quot;(b)        /* output */&lt;br /&gt;
     :&amp;quot;r&amp;quot;(a)         /* input */&lt;br /&gt;
     :&amp;quot;%eax&amp;quot;         /* clobbered register */&lt;br /&gt;
     );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然后，您已经设法使用汇编代码将“a”的值复制到“b”中，在汇编代码中有效地使用了一些C变量。祝贺&lt;br /&gt;
&lt;br /&gt;
最后一个“clobbered register”部分用于告诉GCC您的代码正在使用处理器的一些寄存器，并且在执行asm代码段之前，它应该将正在运行的程序中的所有活动数据移出该寄存器。 在上面的例子中，我们在第一条指令中将&amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;移动到eax，有效地擦除了它的内容，因此我们需要要求GCC在操作之前从未保存的数据中清除该寄存器。&lt;br /&gt;
&lt;br /&gt;
=== 汇编程序模板 ===&lt;br /&gt;
汇编器模板定义要内联的汇编器指令。 默认情况下，此处使用AT&amp;amp;T语法。 如果要使用英特尔语法，应将-masm=Intel&amp;lt;/tt&amp;gt;指定为命令行选项。&lt;br /&gt;
&lt;br /&gt;
例如，要停止CPU，只需使用以下命令：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm( &amp;quot;hlt&amp;quot; );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 输出操作数 ===&lt;br /&gt;
“输出操作数”部分用于告诉编译器/汇编程序如何处理用于存储ASM代码输出的C变量。 输出操作数是一组对，每个操作数由一个字符串文字（称为“约束”）和一个C变量（括号中）组成，该字符串文字说明C变量应映射到哪里（寄存器通常用于最佳性能）。&lt;br /&gt;
&lt;br /&gt;
在约束条件中，“a”表示EAX，“b”表示EBX，“c”表示ECX，“d”表示EDX，“S”表示ESI，“d”表示EDI（请阅读GCC手册中的完整列表），假设您正在为IA32体系结构编码。 等式符号表示程序集代码不关心映射变量的初始值（这允许一些优化）。 考虑到所有这些，现在很清楚下面的代码将EAX设置为0。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int EAX;&lt;br /&gt;
asm( &amp;quot;movl $0, %0&amp;quot;&lt;br /&gt;
   : &amp;quot;=a&amp;quot; (EAX)&lt;br /&gt;
    );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
请注意，编译器将枚举以%0开头的操作数，如果将寄存器用于存储输出操作数，则无需将其添加到已删除的寄存器列表中。 GCC足够聪明，能够自己决定做什么。&lt;br /&gt;
&lt;br /&gt;
从GCC 3.1开始，您可以使用更可读的标签，而不是容易出错的枚举：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int current_task;&lt;br /&gt;
asm( &amp;quot;str %[output]&amp;quot;&lt;br /&gt;
   : [output] &amp;quot;=r&amp;quot; (current_task)&lt;br /&gt;
    );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这些标签位于它们自己的名称空间中，不会与任何C标识符冲突。 对于输入操作数也可以这样做。&lt;br /&gt;
&lt;br /&gt;
=== 输入操作数 ===&lt;br /&gt;
虽然输出操作数通常用于。。。好输出时，输入操作数允许参数化ASM代码；即。， 将只读参数从C代码传递到ASM块。同样，字符串文字用于指定细节。&lt;br /&gt;
&lt;br /&gt;
如果您想将某个值移动到EAX，可以通过以下方式执行（即使这样做而不是直接将该值映射到EAX肯定是毫无用处的）：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int randomness = 4;&lt;br /&gt;
asm( &amp;quot;movl %0, %%eax&amp;quot;&lt;br /&gt;
   :&lt;br /&gt;
   : &amp;quot;b&amp;quot; (randomness)&lt;br /&gt;
   : &amp;quot;eax&amp;quot;&lt;br /&gt;
    );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
请注意，GCC将始终假定输入操作数是只读的（未更改）。 写入输入操作数时，正确的做法是将它们列为输出，但不使用等式符号，因为这一次它们的原始值很重要。 下面是一个简单的例子：&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm(&amp;quot;mov %%eax,%%ebx&amp;quot;: : &amp;quot;a&amp;quot; (amount));//useless but it gets the idea&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Eax will contain &amp;quot;amount&amp;quot; and be moved into ebx.&lt;br /&gt;
&lt;br /&gt;
=== 删除寄存器列表 ===&lt;br /&gt;
记住一件事很重要：“C/C++编译器对汇编器一无所知”。 对于编译器来说，asm语句是不透明的，如果您没有指定任何输出，它甚至可能得出结论，认为这是一个不可操作的语句，并对其进行优化。 一些第三方文档指出，使用asm volatile将导致关键字不被移动。 然而，根据GCC文档，“volatile关键字表示指令有重要的副作用。 如果可以访问易失性asm，GCC将不会删除该asm。''，这只表示它不会被删除 （也就是说，它是否仍然可以移动是一个尚未回答的问题）。 一种可行的方法是使用asm（volatile）并将“内存”放入缓冲寄存器中，如下所示：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
__asm__(&amp;quot;cli&amp;quot;: : :&amp;quot;memory&amp;quot;); // Will cause the statement not to be moved, but it may be optimized away.&lt;br /&gt;
__asm__ __volatile__(&amp;quot;cli&amp;quot;: : :&amp;quot;memory&amp;quot;); // Will cause the statement not to be moved nor optimized away.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
由于编译器使用CPU寄存器对C/C++变量进行内部优化，并且不知道ASM操作码， 您必须警告它，任何寄存器可能会因为副作用而被破坏， 因此，编译器可以在进行ASM调用之前保存它们的内容。&lt;br /&gt;
&lt;br /&gt;
Clobbered Registers列表是一个以逗号分隔的寄存器名列表，以字符串文本形式显示。&lt;br /&gt;
&lt;br /&gt;
=== 通配符：如何让编译器选择 ===&lt;br /&gt;
您不需要告诉编译器在每个操作中应该使用哪个特定寄存器，一般来说， 除非你有充分的理由特别喜欢一个注册， 你最好让编译器替你决定。&lt;br /&gt;
&lt;br /&gt;
例如，强制在任何其他寄存器上使用EAX可能会迫使编译器发出代码，将以前在EAX中的内容保存在其他寄存器中，或者可能会在操作之间引入不必要的依赖关系（管道优化被破坏）&lt;br /&gt;
&lt;br /&gt;
The 'wildcards' constraints allows you to give more freedom to GCC when it comes to input/output mapping:&lt;br /&gt;
{| {{wikitable}}&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;g&amp;quot; constraint : &amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&amp;quot;movl $0, %0&amp;quot; : &amp;quot;=g&amp;quot; (x)&amp;lt;/source&amp;gt;&lt;br /&gt;
| x can be whatever the compiler prefers: a register, a memory reference. It could even be a literal constant in another context.&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;r&amp;quot; constraint : &amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&amp;quot;movl %%es, %0&amp;quot; : &amp;quot;=r&amp;quot; (x)&amp;lt;/source&amp;gt;&lt;br /&gt;
| you want x to go through a register. If x wasn't optimized as a register, the compiler will then move it to the place it should be. This means that &amp;lt;code&amp;gt;&amp;quot;movl %0, %%es&amp;quot; : : &amp;quot;r&amp;quot; (0x38)&amp;lt;/code&amp;gt; is enough to load a segment register.&lt;br /&gt;
|-&lt;br /&gt;
| The &amp;quot;N&amp;quot; constraint : &amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&amp;quot;outl %0, %1&amp;quot; : : &amp;quot;a&amp;quot; (0xFE), &amp;quot;N&amp;quot; (0x21)&amp;lt;/source&amp;gt;&lt;br /&gt;
| tells the value '0x21' can be used as a constant in the out or in operation if ranging from 0 to 255&lt;br /&gt;
|}&lt;br /&gt;
There are of course a lot more constraints you can put on the operand selection, machine-dependent or not, which are listed in GCC's manual (see [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Simple-Constraints.html#Simple-Constraints], [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Modifiers.html#Modifiers], [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Multi_002dAlternative.html#Multi_002dAlternative], and [http://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Machine-Constraints.html#Machine-Constraints]).&lt;br /&gt;
&lt;br /&gt;
== 使用C99 ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;asm&amp;lt;/tt&amp;gt; is not a keyword when using &amp;lt;tt&amp;gt;gcc -std=c99&amp;lt;/tt&amp;gt;. Simply use &amp;lt;tt&amp;gt;gcc -std=gnu99&amp;lt;/tt&amp;gt; to use C99 with GNU extensions. Alternatively, you can use &amp;lt;tt&amp;gt;__asm__&amp;lt;/tt&amp;gt; as an alternate keyword that works even when the compiler strictly adheres to the standard.&lt;br /&gt;
&lt;br /&gt;
== 分配标签 ==&lt;br /&gt;
可以将所谓的ASM标签指定给C/C++关键字。 您可以通过对变量定义使用&amp;lt;tt&amp;gt;asm&amp;lt;/tt&amp;gt;命令来执行此操作，如本例所示：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int some_obscure_name asm(&amp;quot;param&amp;quot;) = 5; // &amp;quot;param&amp;quot; will be accessible in inline Assembly.&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
asm(&amp;quot;mov param, %%eax&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
下面是一个示例，说明如果不显式声明名称，如何访问这些变量：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int some_obscure_name = 5;&lt;br /&gt;
&lt;br /&gt;
void foo()&lt;br /&gt;
{&lt;br /&gt;
asm(&amp;quot;mov some_obscure_name, %%eax&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
请注意，根据您的链接选项，您可能还必须使用“一些模糊的名称”（带前导下划线）。&lt;br /&gt;
&lt;br /&gt;
== asm goto ==&lt;br /&gt;
在GCC4.5之前，不支持跨内联装配块跳转。编译器无法跟踪正在发生的事情，&lt;br /&gt;
因此，几乎可以保证生成错误的代码。&lt;br /&gt;
&amp;lt;br&amp;gt;你可能会被告知“gotos是邪恶的”。 如果你相信这是真的，那么asm gotos就是你最可怕的噩梦。&lt;br /&gt;
然而，它们确实提供了一些有趣的代码优化选项。&lt;br /&gt;
&lt;br /&gt;
asm goto没有很好的文档记录，但其语法如下：&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 asm goto( &amp;quot;jmp %l[labelname]&amp;quot; : /* no outputs */ : /* inputs */ : &amp;quot;memory&amp;quot; /* clobbers */ : labelname /* any labels used */ );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CMPXCHG指令就是一个很有用的例子（参见[http://en.wikipedia.org/wiki/Compare-and-swapLinux内核源代码对其定义如下：&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* TODO: You should use modern GCC atomic instruction builtins instead of this. */&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#define cmpxchg( ptr, _old, _new ) { \&lt;br /&gt;
  volatile uint32_t *__ptr = (volatile uint32_t *)(ptr);   \&lt;br /&gt;
  uint32_t __ret;                                     \&lt;br /&gt;
  asm volatile( &amp;quot;lock; cmpxchgl %2,%1&amp;quot;           \&lt;br /&gt;
    : &amp;quot;=a&amp;quot; (__ret), &amp;quot;+m&amp;quot; (*__ptr)                \&lt;br /&gt;
    : &amp;quot;r&amp;quot; (_new), &amp;quot;0&amp;quot; (_old)                     \&lt;br /&gt;
    : &amp;quot;memory&amp;quot;);				 \&lt;br /&gt;
  );                                             \&lt;br /&gt;
  __ret;                                         \&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
除了返回EAX中的当前值，CMPXCHG在成功时设置零标志（Z）。 如果没有asm gotos，代码将必须检查返回值；&lt;br /&gt;
此CMP指令可以通过以下方式避免：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* TODO: You should use modern GCC atomic instruction builtins instead of this. */&lt;br /&gt;
// Works for both 32 and 64 bit&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#define cmpxchg( ptr, _old, _new, fail_label ) { \&lt;br /&gt;
  volatile uint32_t *__ptr = (volatile uint32_t *)(ptr);   \&lt;br /&gt;
  asm goto( &amp;quot;lock; cmpxchg %1,%0 \t\n&amp;quot;           \&lt;br /&gt;
    &amp;quot;jnz %l[&amp;quot; #fail_label &amp;quot;] \t\n&amp;quot;               \&lt;br /&gt;
    : /* empty */                                \&lt;br /&gt;
    : &amp;quot;m&amp;quot; (*__ptr), &amp;quot;r&amp;quot; (_new), &amp;quot;a&amp;quot; (_old)       \&lt;br /&gt;
    : &amp;quot;memory&amp;quot;, &amp;quot;cc&amp;quot;                             \&lt;br /&gt;
    : fail_label );                              \&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然后可以按如下方式使用此新宏：&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
struct Item {&lt;br /&gt;
volatile struct Item* next;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
volatile struct Item *head;&lt;br /&gt;
&lt;br /&gt;
void addItem( struct Item *i ) {&lt;br /&gt;
volatile struct Item *oldHead;&lt;br /&gt;
again:&lt;br /&gt;
oldHead = head;&lt;br /&gt;
i-&amp;gt;next = oldHead;&lt;br /&gt;
cmpxchg( &amp;amp;head, oldHead, i, again );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 英特尔语法 ==&lt;br /&gt;
通过在内联汇编中启用，您可以让GCC使用intel语法，如下所示：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm(&amp;quot;.intel_syntax noprefix&amp;quot;);&lt;br /&gt;
asm(&amp;quot;mov eax, ebx&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
类似地，您可以使用以下代码段切换回AT&amp;amp;T语法：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
asm(&amp;quot;.att_syntax prefix&amp;quot;);&lt;br /&gt;
asm(&amp;quot;mov %ebx, %eax&amp;quot;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
通过这种方式，您可以将Intel语法和AT&amp;amp;T语法内联汇编结合起来。 请注意，一旦触发其中一种语法类型，源文件中命令下面的所有内容都将使用此语法进行组装， 因此，在必要时不要忘记切换回来，否则可能会出现大量编译错误！&lt;br /&gt;
&lt;br /&gt;
还有一个命令行选项&amp;lt;tt&amp;gt;-masm=intel&amp;lt;/tt&amp;gt;，用于全局触发英特尔语法。&lt;br /&gt;
&lt;br /&gt;
== 另见 ==&lt;br /&gt;
&lt;br /&gt;
=== Articles ===&lt;br /&gt;
* [[Inline Assembly/Examples]] - useful and commonly used functions&lt;br /&gt;
&lt;br /&gt;
=== Forum Threads ===&lt;br /&gt;
* [http://forum.osdev.org/viewtopic.php?f=11&amp;amp;t=24168&amp;amp;p=196655&amp;amp;hilit=asm+volatile+moved asm volatile being moved]&lt;br /&gt;
&lt;br /&gt;
=== 外部 ===&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/ GCC Manuals]&lt;br /&gt;
* [http://web.archive.org/web/20041210030000/http://www-106.ibm.com/developerworks/library/l-ia.html Inline assembly for x86 in Linux (by IBM)]&lt;br /&gt;
* [http://msdn.microsoft.com/en-us/library/26td21ds(VS.80).aspx Visual C++ Compiler Intrinsics]&lt;br /&gt;
&lt;br /&gt;
[[Category:Assembly]]&lt;br /&gt;
[[de:Inline-Assembler_mit_GCC]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>