⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 using_in-line_assembly_calling_external_assembly_from_c.html

📁 ADI 公司blackfin系列的用户使用文挡。
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head>  <title></title>  <link rel="stylesheet" media="screen" type="text/css" href="./style.css" />  <link rel="stylesheet" media="screen" type="text/css" href="./design.css" />  <link rel="stylesheet" media="print" type="text/css" href="./print.css" />  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body><a href=start.html>start</a></br><h2><a name="using_in-line_assembly_calling_external_assembly_from_c" id="using_in-line_assembly_calling_external_assembly_from_c">Using In-line Assembly, Calling External Assembly from C</a></h2><div class="level2"><p>In-line assembly refers to placing assembly code within C code, this can be done in two ways:  through the use of the <em><strong>asm</strong></em><em><strong> </strong></em>construct, or by calling assembly code subroutines which are defined in a separate file.  The <em><strong>asm</strong></em> construct method will be discussed first.  The general format of the <em><strong>asm</strong></em> construct is given below:</p><p><strong>asm( assembler template [: output operands : input operands : list of clobbered registers])</strong> </p><ul><li class="level1"><div class="li"> <strong>assembler template</strong> - This is the template from which the assembler code will be generated.  The assembler instruction(s) given here must be enclosed in double quotes (&rdquo; &ldquo;).  Each instruction must be followed by a delimiter, either a newline (\n) or a semicolon.  To access the output and input operands the following syntax is used:  %0 (for the first operand), %1 (for the second operand),...etc.</div></li><li class="level1"><div class="li"> <strong>output operands</strong> -This is a list of C expressions which can be written to by instructions in the  assembler template.  The format of an output operand is &ldquo;constraint&rdquo; (C expression).  Each output operand must be separated by a comma.</div></li><li class="level1"><div class="li"> <strong>input operands</strong> -This is a list of C expressions which can be read by the instructions in the assembler template.  The format of an input operand is &ldquo;constraint&rdquo; (C expression).  Each input operand must be separated by a comma.</div></li><li class="level1"><div class="li"> <strong>list of clobbered registers</strong> - Any registers which are modified by the assembly instructions must be listed here.  This will prevent the compiler from using these registers for other purposes.  Each register in the list is enclosed in double quotes (&rdquo; &ldquo;) and separated from other registers in the list by a comma.</div></li></ul><p>  <em><strong>__asm__</strong></em><em><strong>asm</strong></em> </p><p>A summary of the most common constraints for input and output operands are given below: </p><ul><li class="level1"><div class="li"> <strong>m, memory operand</strong> - This constraint specifies that the variable&rsquo;s memory location should be used when referencing the operand.  The value will not be copied to a register, instead all read and write operations will be preformed directly at the specified memory location.  This frees up registers for other purposes.</div></li><li class="level1"><div class="li"> <strong>r, register operand</strong> - This constraint specifies that the given operand should be stored in a general purpose register.  This option should be used only when necessary or when it significantly speeds up execution.</div></li><li class="level1"><div class="li"> <strong>[0,1,2,...], matching</strong> - This constraint is used when the same variable is to be used for both input and output.  The number corresponding to the variable to be matched is used to specify a matching constraint (e.g. &ldquo;0&rdquo; means same as the first variable, &ldquo;1&rdquo; means same as the second variable, etc.).</div></li><li class="level1"><div class="li"> <strong>=, write-only</strong> - This modifier specifies that the operand is write only.  Any previously value is overwritten with the new value.</div></li></ul><p> The gcc website maintains an exhaustive list of <a href="http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html" class="urlextern" title="http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html"  rel="nofollow">machine constraints</a>. Just scroll down a few pages to the <code>Blackfin family</code> section.</p><p> Another consideration is whether or not the assembly code should be specified as volatile.  If the code must remain in a certain location or should not otherwise be optimized by the compiler the <em><strong>volatile</strong></em> construct should be used after the <em><strong>asm</strong></em> construct (i.e. <em><strong>asm volatile (...) </strong></em>).</p><p> Some examples of in-line assembly are given below:</p><pre class="code">int x =10; int y; asm( &quot;%0 = %1&quot;: &quot;=r&quot;(y) : &quot;m&quot;(x) );</pre><p>This example simply makes the assignment <em><strong>y=x</strong></em>.  The variable <em><strong>y</strong></em> is specified as a write-only, register constrained, output operand.  The variable <em><strong>x </strong></em>is a memory constrained input operand.  Since the variable <em><strong>y</strong></em> is first in the operand list, it is specified in the assembler template with <em><strong>%0</strong></em>, <em><strong>%1</strong></em> corresponds to <em><strong>x</strong></em>.  Neglecting complier optimization, the generated assembly code will load the value of <em><strong>x</strong></em> directly from its memory location into a general purpose register corresponding to <em><strong>y</strong></em>.  The value of this general purpose register will then be copied to <em><strong>y</strong></em>.  A list of clobbered registers is not required as the registers used are selected by the complier and not specified by the assembler template.</p><pre class="code">int x =10; int y; asm( &quot;%0 = %1&quot;: &quot;=r&quot;(y) : &quot;r&quot;(x) );</pre><p>This example is the same as the one above except that <em><strong>x </strong></em>is now a register constrained input operand.  Neglecting complier optimization, the generated assembly code will copy the value of <em><strong>x</strong></em> to a general purpose register, load the value of this general purpose register into a second general purpose register corresponding to <em><strong>y</strong></em>, then copy the value of this second general purpose register to <em><strong>y</strong></em>.  Again, a list of clobbered registers is not required as the registers used are selected by the complier and not specified by the assembler template.</p><pre class="code">int x=0x00FF; asm( &quot;%0 = %1 &lt;&lt; 4&quot; : &quot;=r&quot;(x) : &quot;0&quot;(x) );</pre><p>This is an example of the matching constraint.  Here <em><strong>x </strong></em>is a register constrained output operand as well as an input operand.  The &ldquo;0&rdquo; constraint specifies that <em><strong>x</strong></em>, in the input operand list, is the same as the first variable (i.e. <em><strong>x</strong></em> in the output operand list).  This piece of assembler code simply shifts <em><strong>x</strong></em> left 4 bits producing the output <em><strong>x=0x0FF0</strong></em>.</p><pre class="code">int x=10; int y; asm( &quot;R0 = %1;R1 = R0;%0 = R1&quot; : &quot;=r&quot;(y) : &quot;m&quot;(x) : &quot;R0&quot;,&quot;R1&quot; );</pre><p>This example demonstrates the need for the clobbered register list.  Neglecting complier optimization, this piece of assembly code copies the value of x to R0 then copies this to R1, finally writing R1 to y.  In this case the assembler template changes the value of registers R0 and R1 so they must be included in the clobbered register list.</p><p> Many more features are available for use with the <em><strong>asm</strong></em> construct.  For more information on this topic see:  <a href="http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html" class="urlextern" title="http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html"  rel="nofollow">GCC-Inline-Assembly-HOWTO</a>.</p><p> The other method of including assembly instructions within C code is to call assembly code subroutines which are defined in a separate file, an example of this is given below.</p><p> To call a simple assembly subroutine which adds two numbers together and returns the result, C code similar to the following could be used:</p><pre class="code c"><span class="kw2">extern</span> <span class="kw4">int</span> addition<span class="br0">&#40;</span><span class="kw4">int</span>,<span class="kw4">int</span><span class="br0">&#41;</span>;&nbsp;<span class="kw4">int</span> main<span class="br0">&#40;</span><span class="kw4">void</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="kw4">int</span> result;result = addition<span class="br0">&#40;</span><span class="nu0">1</span>,<span class="nu0">2</span><span class="br0">&#41;</span>;<a href="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">"Result = %i<span class="es0">\n</span>"</span>,result<span class="br0">&#41;</span>;<span class="kw1">return</span> <span class="nu0">0</span>;<span class="br0">&#125;</span></pre><p>The <em><strong>extern</strong></em> keyword tells the compiler that the <em><strong>addition</strong></em> subroutine is defined in another file.  This file would contain assembly instructions similar to the following:</p><pre class="code">.global _addition; _addition: R0 =R0+R1; RTS;</pre><p><em><strong>.global</strong></em> is an assembler directive, it makes the symbol <em><strong>_addition</strong></em> visible to the linker so that it may be linked to the externally defined function <em><strong>addition</strong></em> in the C code.  Assembler directives always begin with a period.</p>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -