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

📄 extended-asm.html

📁 自己收集的linux入门到学懂高级编程书集 包括linux程序设计第三版
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html lang="en"><head><title>Using the GNU Compiler Collection (GCC)</title><meta http-equiv="Content-Type" content="text/html"><meta name="description" content="Using the GNU Compiler Collection (GCC)"><meta name="generator" content="makeinfo 4.6"><!--Copyright &copy; 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.   <p>Permission is granted to copy, distribute and/or modify this documentunder the terms of the GNU Free Documentation License, Version 1.2 orany later version published by the Free Software Foundation; with theInvariant Sections being "GNU General Public License" and "FundingFree Software", the Front-Cover texts being (a) (see below), and withthe Back-Cover Texts being (b) (see below).  A copy of the license isincluded in the section entitled "GNU Free Documentation License".   <p>(a) The FSF's Front-Cover Text is:   <p>A GNU Manual   <p>(b) The FSF's Back-Cover Text is:   <p>You have freedom to copy and modify this GNU Manual, like GNU     software.  Copies published by the Free Software Foundation raise     funds for GNU development.--><meta http-equiv="Content-Style-Type" content="text/css"><style type="text/css"><!--  pre.display { font-family:inherit }  pre.format  { font-family:inherit }  pre.smalldisplay { font-family:inherit; font-size:smaller }  pre.smallformat  { font-family:inherit; font-size:smaller }  pre.smallexample { font-size:smaller }  pre.smalllisp    { font-size:smaller }--></style></head><body><div class="node"><p>Node:&nbsp;<a name="Extended%20Asm">Extended Asm</a>,Next:&nbsp;<a rel="next" accesskey="n" href="Constraints.html#Constraints">Constraints</a>,Previous:&nbsp;<a rel="previous" accesskey="p" href="Inline.html#Inline">Inline</a>,Up:&nbsp;<a rel="up" accesskey="u" href="C-Extensions.html#C%20Extensions">C Extensions</a><hr><br></div><h3 class="section">Assembler Instructions with C Expression Operands</h3><p>In an assembler instruction using <code>asm</code>, you can specify theoperands of the instruction using C expressions.  This means you need notguess which registers or memory locations will contain the data you wantto use.   <p>You must specify an assembler instruction template much like whatappears in a machine description, plus an operand constraint string foreach operand.   <p>For example, here is how to use the 68881's <code>fsinx</code> instruction:<pre class="smallexample">     asm ("fsinx %1,%0" : "=f" (result) : "f" (angle));     </pre><p>Here <code>angle</code> is the C expression for the input operand while<code>result</code> is that of the output operand.  Each has <code>"f"</code> as itsoperand constraint, saying that a floating point register is required. The <code>=</code> in <code>=f</code> indicates that the operand is an output; alloutput operands' constraints must use <code>=</code>.  The constraints use thesame language used in the machine description (see <a href="Constraints.html#Constraints">Constraints</a>).   <p>Each operand is described by an operand-constraint string followed bythe C expression in parentheses.  A colon separates the assemblertemplate from the first output operand and another separates the lastoutput operand from the first input, if any.  Commas separate theoperands within each group.  The total number of operands is currentlylimited to 30; this limitation may be lifted in some future version ofGCC.   <p>If there are no output operands but there are input operands, you mustplace two consecutive colons surrounding the place where the outputoperands would go.   <p>As of GCC version 3.1, it is also possible to specify input and outputoperands using symbolic names which can be referenced within theassembler code.  These names are specified inside square bracketspreceding the constraint string, and can be referenced inside theassembler code using <code>%[</code><var>name</var><code>]</code> instead of a percentage signfollowed by the operand number.  Using named operands the above examplecould look like:<pre class="smallexample">     asm ("fsinx %[angle],%[output]"          : [output] "=f" (result)          : [angle] "f" (angle));     </pre><p>Note that the symbolic operand names have no relation whatsoever toother C identifiers.  You may use any name you like, even those ofexisting C symbols, but you must ensure that no two operands within the sameassembler construct use the same symbolic name.   <p>Output operand expressions must be lvalues; the compiler can check this. The input operands need not be lvalues.  The compiler cannot checkwhether the operands have data types that are reasonable for theinstruction being executed.  It does not parse the assembler instructiontemplate and does not know what it means or even whether it is validassembler input.  The extended <code>asm</code> feature is most often used formachine instructions the compiler itself does not know exist.  Ifthe output expression cannot be directly addressed (for example, it is abit-field), your constraint must allow a register.  In that case, GCCwill use the register as the output of the <code>asm</code>, and then storethat register into the output.   <p>The ordinary output operands must be write-only; GCC will assume thatthe values in these operands before the instruction are dead and neednot be generated.  Extended asm supports input-output or read-writeoperands.  Use the constraint character <code>+</code> to indicate such anoperand and list it with the output operands.  You should only useread-write operands when the constraints for the operand (or theoperand in which only some of the bits are to be changed) allow aregister.   <p>You may, as an alternative, logically split its function into twoseparate operands, one input operand and one write-only outputoperand.  The connection between them is expressed by constraintswhich say they need to be in the same location when the instructionexecutes.  You can use the same C expression for both operands, ordifferent expressions.  For example, here we write the (fictitious)<code>combine</code> instruction with <code>bar</code> as its read-only sourceoperand and <code>foo</code> as its read-write destination:<pre class="smallexample">     asm ("combine %2,%0" : "=r" (foo) : "0" (foo), "g" (bar));     </pre><p>The constraint <code>"0"</code> for operand 1 says that it must occupy thesame location as operand 0.  A number in constraint is allowed only inan input operand and it must refer to an output operand.   <p>Only a number in the constraint can guarantee that one operand will be inthe same place as another.  The mere fact that <code>foo</code> is the valueof both operands is not enough to guarantee that they will be in thesame place in the generated assembler code.  The following would notwork reliably:<pre class="smallexample">     asm ("combine %2,%0" : "=r" (foo) : "r" (foo), "g" (bar));     </pre>   <p>Various optimizations or reloading could cause operands 0 and 1 to be indifferent registers; GCC knows no reason not to do so.  For example, thecompiler might find a copy of the value of <code>foo</code> in one register anduse it for operand 1, but generate the output operand 0 in a differentregister (copying it afterward to <code>foo</code>'s own address).  Of course,since the register for operand 1 is not even mentioned in the assemblercode, the result will not work, but GCC can't tell that.   <p>As of GCC version 3.1, one may write <code>[</code><var>name</var><code>]</code> instead ofthe operand number for a matching constraint.  For example:<pre class="smallexample">     asm ("cmoveq %1,%2,%[result]"          : [result] "=r"(result)          : "r" (test), "r"(new), "[result]"(old));     </pre>   <p>Some instructions clobber specific hard registers.  To describe this,write a third colon after the input operands, followed by the names ofthe clobbered hard registers (given as strings).  Here is a realisticexample for the VAX:<pre class="smallexample">     asm volatile ("movc3 %0,%1,%2"                   : /* no outputs */                   : "g" (from), "g" (to), "g" (count)                   : "r0", "r1", "r2", "r3", "r4", "r5");     </pre>   <p>You may not write a clobber description in a way that overlaps with aninput or output operand.  For example, you may not have an operanddescribing a register class with one member if you mention that registerin the clobber list.  Variables declared to live in specific registers(see <a href="Explicit-Reg-Vars.html#Explicit%20Reg%20Vars">Explicit Reg Vars</a>), and used as asm input or output operands musthave no part mentioned in the clobber description. There is no way for you to specify that an inputoperand is modified without also specifying it as an outputoperand.  Note that if all the output operands you specify are for thispurpose (and hence unused), you will then also need to specify<code>volatile</code> for the <code>asm</code> construct, as described below, toprevent GCC from deleting the <code>asm</code> statement as unused.   <p>If you refer to a particular hardware register from the assembler code,you will probably have to list the register after the third colon totell the compiler the register's value is modified.  In some assemblers,the register names begin with <code>%</code>; to produce one <code>%</code> in theassembler code, you must write <code>%%</code> in the input.   <p>If your assembler instruction can alter the condition code register, add<code>cc</code> to the list of clobbered registers.  GCC on some machinesrepresents the condition codes as a specific hardware register;<code>cc</code> serves to name this register.  On other machines, thecondition code is handled differently, and specifying <code>cc</code> has noeffect.  But it is valid no matter what the machine.   <p>If your assembler instructions access memory in an unpredictablefashion, add <code>memory</code> to the list of clobbered registers.  Thiswill cause GCC to not keep memory values cached in registers across theassembler instruction and not optimize stores or loads to that memory. You will also want to add the <code>volatile</code> keyword if the memoryaffected is not listed in the inputs or outputs of the <code>asm</code>, asthe <code>memory</code> clobber does not count as a side-effect of the<code>asm</code>.  If you know how large the accessed memory is, you can addit as input or output but if this is not known, you should add<code>memory</code>.  As an example, if you access ten bytes of a string, youcan use a memory input like:<pre class="example">     {"m"( ({ struct { char x[10]; } *p = (void *)ptr ; *p; }) )}.     </pre>   <p>Note that in the following example the memory input is necessary,otherwise GCC might optimize the store to <code>x</code> away:<pre class="example">     int foo ()     {       int x = 42;       int *y = &amp;x;       int result;       asm ("magic stuff accessing an 'int' pointed to by '%1'"             "=&amp;d" (r) : "a" (y), "m" (*y));       return result;     }     </pre>   <p>You can put multiple assembler instructions together in a single<code>asm</code> template, separated by the characters normally used in assemblycode for the system.  A combination that works in most places is a newlineto break the line, plus a tab character to move to the instruction field(written as <code>\n\t</code>).  Sometimes semicolons can be used, if theassembler allows semicolons as a line-breaking character.  Note that some

⌨️ 快捷键说明

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