140 lines
11 KiB
HTML
140 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh" dir="ltr" class="client-nojs" xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
<head><meta http-equiv="x-ua-compatible" content="ie=edge">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<title>内联汇编</title>
|
|
<link rel="stylesheet" href="ext.css" />
|
|
<link rel="stylesheet" href="site_modules.css" />
|
|
</head>
|
|
<body class="mediawiki ltr sitedir-ltr ns-0 ns-subject page-c_language_asm skin-cppreference2 action-view cpp-navbar">
|
|
<div id="cpp-content-base">
|
|
<div id="content"><a id="top"></a>
|
|
<h1 id="firstHeading" class="firstHeading">内联汇编</h1>
|
|
<div id="bodyContent">
|
|
<div id="contentSub"><span class="subpages">< <a href="c.html">c</a>‎ | <a href="c-language.html">language</a></span></div>
|
|
<div id="mw-content-text" lang="zh" dir="ltr" class="mw-content-ltr" xml:lang="zh">
|
|
<p>内联汇编(常由 <span class="t-c"><span class="mw-geshi c source-c">asm</span></span> 关键词引入)给予在 C 程序中嵌入汇编语言源代码的能力。</p>
|
|
<p>不同于 C++ 中,内联汇编在 C 中被当作扩展。它是条件性支持及由实现定义的,意思是它可以不存在,而且即使实现有所提供,它也并不拥有固定的含义。</p>
|
|
<h3><span class="mw-headline" id=".E8.AF.AD.E6.B3.95">语法</span></h3>
|
|
<table class="t-sdsc-begin">
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
<tr class="t-sdsc">
|
|
<td class="t-sdsc-nopad"><code><b>asm (</b></code> <span class="t-spar">字符串字面量</span> <code><b>)</b></code> <code><b>;</b></code></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
<td class="t-sdsc-nopad"></td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="10" class="t-sdsc-sep"></td>
|
|
</tr>
|
|
</table>
|
|
<table class="metadata plainlinks ambox mbox-small-left ambox-notice" style="">
|
|
<tr>
|
|
<td class="mbox-empty-cell"></td>
|
|
<td class="mbox-text" style="">本节未完成<br />
|
|
原因:写下关于 GCC 扩展汇编语法的注解,因为现在 Intel、IBM、Sun(自 v12 起)等均支持它</td>
|
|
</tr>
|
|
</table>
|
|
<h3><span class="mw-headline" id=".E8.A7.A3.E9.87.8A">解释</span></h3>
|
|
<p>这种内联汇编语法为 C++ 标准所接受,而在 C++ 中称为<i>汇编声明</i>。 <span class="t-spar">字符串字面量</span> 通常是以汇编语言编写的短程序,每当执行这条声明时对其执行。不同的 C 编译器拥有差异巨大的汇编声明规则,和与周围的 C 代码之间交互的不同约定。</p>
|
|
<p>汇编声明可出现于块(函数体或其他复合语句)内,而且同所有其他声明,此声明亦可出现于块外。</p>
|
|
<h3><span class="mw-headline" id=".E6.B3.A8.E8.A7.A3">注解</span></h3>
|
|
<p>MSVC 在 ARM 与 x64 处理器上不支持内联汇编,而且在 x86 处理器上仅支持由 <span class="t-c"><span class="mw-geshi c source-c">__asm</span></span> 引入的形式。</p>
|
|
<p>以 GCC 或 Clang 用 ISO C 模式编译(例如以选项 <span class="t-c"><span class="mw-geshi c source-c"><span class="sy2">-</span>std<span class="sy1">=</span>c11</span></span> )时,必须用 <span class="t-c"><span class="mw-geshi c source-c">__asm__</span></span> 代替 <span class="t-c"><span class="mw-geshi c source-c">asm</span></span> 。</p>
|
|
<h3><span class="mw-headline" id=".E7.A4.BA.E4.BE.8B">示例</span></h3>
|
|
<div class="t-example">
|
|
<p>演示 GCC 提供的二种内联汇编语法。此程序将只在 x86-64 上的 Linux 下正确工作。注意“标准内联汇编”在 C 标准中亦被当作扩展。</p>
|
|
<div class="t-example-live-link"></div>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="c source-c">
|
|
<pre class="de1"><span class="co2">#include <stdio.h></span>
|
|
|
|
<span class="kw2">extern</span> <span class="kw4">int</span> func<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="co1">// func 的定义以汇编语言书写</span>
|
|
__asm__<span class="br0">(</span><span class="st0">".globl func<span class="es1">\n</span><span class="es1">\t</span>"</span>
|
|
<span class="st0">".type func, @function<span class="es1">\n</span><span class="es1">\t</span>"</span>
|
|
<span class="st0">"func:<span class="es1">\n</span><span class="es1">\t</span>"</span>
|
|
<span class="st0">".cfi_startproc<span class="es1">\n</span><span class="es1">\t</span>"</span>
|
|
<span class="st0">"movl $7, %eax<span class="es1">\n</span><span class="es1">\t</span>"</span>
|
|
<span class="st0">"ret<span class="es1">\n</span><span class="es1">\t</span>"</span>
|
|
<span class="st0">".cfi_endproc"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
|
|
<span class="kw4">int</span> main<span class="br0">(</span><span class="kw4">void</span><span class="br0">)</span>
|
|
<span class="br0">{</span>
|
|
<span class="kw4">int</span> n <span class="sy1">=</span> func<span class="br0">(</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="co1">// gcc 的扩展内联汇编</span>
|
|
__asm__ <span class="br0">(</span><span class="st0">"leal (%0,%0,4),%0"</span>
|
|
<span class="sy4">:</span> <span class="st0">"=r"</span> <span class="br0">(</span>n<span class="br0">)</span>
|
|
<span class="sy4">:</span> <span class="st0">"0"</span> <span class="br0">(</span>n<span class="br0">)</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="c-io-fprintf.html"><span class="kw851">printf</span></a><span class="br0">(</span><span class="st0">"7*5 = %d<span class="es1">\n</span>"</span>, n<span class="br0">)</span><span class="sy4">;</span>
|
|
<a href="c-io-fflush.html"><span class="kw821">fflush</span></a><span class="br0">(</span><a href="c-io.html"><span class="kw887">stdout</span></a><span class="br0">)</span><span class="sy4">;</span> <span class="co1">// 冲刷是有意的</span>
|
|
|
|
<span class="co1">// C++ 中的标准内联汇编</span>
|
|
__asm__ <span class="br0">(</span><span class="st0">"movq $60, %rax<span class="es1">\n</span><span class="es1">\t</span>"</span> <span class="co1">// Linux 上的“退出”的系统调用序号</span>
|
|
<span class="st0">"movq $2, %rdi<span class="es1">\n</span><span class="es1">\t</span>"</span> <span class="co1">// 此程序返回 2</span>
|
|
<span class="st0">"syscall"</span><span class="br0">)</span><span class="sy4">;</span>
|
|
<span class="br0">}</span></pre></div>
|
|
</div>
|
|
<p>输出:</p>
|
|
<div dir="ltr" class="mw-geshi" style="text-align: left;">
|
|
<div class="text source-text">
|
|
<pre class="de1">7*5 = 35</pre></div>
|
|
</div>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.A4.96.E9.83.A8.E9.93.BE.E6.8E.A5">外部链接</span></h3>
|
|
<ul>
|
|
<li><a rel="nofollow" class="external text" href="http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html">GCC 内联汇编 HOWTO</a></li>
|
|
<li><a rel="nofollow" class="external text" href="http://pic.dhe.ibm.com/infocenter/comphelp/v121v141/topic/com.ibm.xlcpp121.aix.doc/language_ref/asm.html">IBM XL C/C++ 内联汇编</a></li>
|
|
<li><a rel="nofollow" class="external text" href="https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-inline-assembly">Intel C++ 内联汇编</a></li>
|
|
<li><a rel="nofollow" class="external text" href="http://msdn.microsoft.com/en-us/library/4ks26t93(v=vs.120).aspx">Visual Studio 2013 内联汇编器</a></li>
|
|
<li><a rel="nofollow" class="external text" href="https://blogs.oracle.com/x86be/entry/gcc_style_asm_inlining_support">Sun Studio 12 Asm 语句</a></li>
|
|
<li><a rel="nofollow" class="external text" href="http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801?ciid=4308e2f5bde02110e2f5bde02110275d6e10RCRD">基于 Itanium 的 HP-UX 的内联汇编</a></li>
|
|
</ul>
|
|
<h3><span class="mw-headline" id=".E5.BC.95.E7.94.A8">引用</span></h3>
|
|
<div class="t-ref-std-11">
|
|
<ul>
|
|
<li>C11 标准(ISO/IEC 9899:2011):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>J.5.10 The asm keyword (p: 580)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c99">
|
|
<ul>
|
|
<li>C99 标准(ISO/IEC 9899:1999):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>J.5.10 The asm keyword (p: 512)</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<div class="t-ref-std-c89">
|
|
<ul>
|
|
<li>C89/C90 标准(ISO/IEC 9899:1990):</li>
|
|
</ul>
|
|
<dl>
|
|
<dd>
|
|
<ul>
|
|
<li>G.5.10 The asm keyword</li>
|
|
</ul>
|
|
</dd>
|
|
</dl>
|
|
</div>
|
|
<h3><span class="mw-headline" id=".E5.8F.82.E9.98.85">参阅</span></h3>
|
|
<table class="t-dsc-begin"></table>
|
|
</div>
|
|
<div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|