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

📄 extended-asm.html

📁 gcc手册
💻 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.3">

<link href="http://www.gnu.org/software/texinfo/" rel="generator-home">

<!--

Copyright &copy; 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,

1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.



   <p>Permission is granted to copy, distribute and/or modify this document

under the terms of the GNU Free Documentation License, Version 1.2 or

any later version published by the Free Software Foundation; with the

Invariant Sections being "GNU General Public License" and "Funding

Free Software", the Front-Cover texts being (a) (see below), and with

the Back-Cover Texts being (b) (see below).  A copy of the license is

included 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.-->

</head>

<body>

<div class="node">

<p>

Node:<a name="Extended%20Asm">Extended Asm</a>,

Next:<a rel="next" accesskey="n" href="Constraints.html#Constraints">Constraints</a>,

Previous:<a rel="previous" accesskey="p" href="Inline.html#Inline">Inline</a>,

Up:<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 the

operands of the instruction using C expressions.  This means you need not

guess which registers or memory locations will contain the data you want

to use.



   <p>You must specify an assembler instruction template much like what

appears in a machine description, plus an operand constraint string for

each operand.



   <p>For example, here is how to use the 68881's <code>fsinx</code> instruction:



<pre class="example">     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 its

operand constraint, saying that a floating point register is required. 

The <code>=</code> in <code>=f</code> indicates that the operand is an output; all

output operands' constraints must use <code>=</code>.  The constraints use the

same 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 by

the C expression in parentheses.  A colon separates the assembler

template from the first output operand and another separates the last

output operand from the first input, if any.  Commas separate the

operands within each group.  The total number of operands is currently

limited to 30; this limitation may be lifted in some future version of

GCC.



   <p>If there are no output operands but there are input operands, you must

place two consecutive colons surrounding the place where the output

operands would go.



   <p>As of GCC version 3.1, it is also possible to specify input and output

operands using symbolic names which can be referenced within the

assembler code.  These names are specified inside square brackets

preceding the constraint string, and can be referenced inside the

assembler code using <code>%[</code><var>name</var><code>]</code> instead of a percentage sign

followed by the operand number.  Using named operands the above example

could look like:



<pre class="example">     asm ("fsinx %[angle],%[output]"

          : [output] "=f" (result)

          : [angle] "f" (angle));

     </pre>



<p>Note that the symbolic operand names have no relation whatsoever to

other C identifiers.  You may use any name you like, even those of

existing C symbols, but must ensure that no two operands within the same

assembler 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 check

whether the operands have data types that are reasonable for the

instruction being executed.  It does not parse the assembler instruction

template and does not know what it means or even whether it is valid

assembler input.  The extended <code>asm</code> feature is most often used for

machine instructions the compiler itself does not know exist.  If

the output expression cannot be directly addressed (for example, it is a

bit-field), your constraint must allow a register.  In that case, GCC

will use the register as the output of the <code>asm</code>, and then store

that register into the output.



   <p>The ordinary output operands must be write-only; GCC will assume that

the values in these operands before the instruction are dead and need

not be generated.  Extended asm supports input-output or read-write

operands.  Use the constraint character <code>+</code> to indicate such an

operand and list it with the output operands.



   <p>When the constraints for the read-write operand (or the operand in which

only some of the bits are to be changed) allows a register, you may, as

an alternative, logically split its function into two separate operands,

one input operand and one write-only output operand.  The connection

between them is expressed by constraints which say they need to be in

the same location when the instruction executes.  You can use the same C

expression for both operands, or different expressions.  For example,

here we write the (fictitious) <code>combine</code> instruction with

<code>bar</code> as its read-only source operand and <code>foo</code> as its

read-write destination:



<pre class="example">     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 the

same location as operand 0.  A number in constraint is allowed only in

an input operand and it must refer to an output operand.



   <p>Only a number in the constraint can guarantee that one operand will be in

the same place as another.  The mere fact that <code>foo</code> is the value

of both operands is not enough to guarantee that they will be in the

same place in the generated assembler code.  The following would not

work reliably:



<pre class="example">     asm ("combine %2,%0" : "=r" (foo) : "r" (foo), "g" (bar));

     </pre>



   <p>Various optimizations or reloading could cause operands 0 and 1 to be in

different registers; GCC knows no reason not to do so.  For example, the

compiler might find a copy of the value of <code>foo</code> in one register and

use it for operand 1, but generate the output operand 0 in a different

register (copying it afterward to <code>foo</code>'s own address).  Of course,

since the register for operand 1 is not even mentioned in the assembler

code, 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 of

the operand number for a matching constraint.  For example:



<pre class="example">     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 of

the clobbered hard registers (given as strings).  Here is a realistic

example for the VAX:



<pre class="example">     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 an

input or output operand.  For example, you may not have an operand

describing a register class with one member if you mention that register

in 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 must

have no part mentioned in the clobber description. 

There is no way for you to specify that an input

operand is modified without also specifying it as an output

operand.  Note that if all the output operands you specify are for this

purpose (and hence unused), you will then also need to specify

<code>volatile</code> for the <code>asm</code> construct, as described below, to

prevent 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 to

tell the compiler the register's value is modified.  In some assemblers,

the register names begin with <code>%</code>; to produce one <code>%</code> in the

assembler 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 machines

represents the condition codes as a specific hardware register;

<code>cc</code> serves to name this register.  On other machines, the

condition code is handled differently, and specifying <code>cc</code> has no

effect.  But it is valid no matter what the machine.



   <p>If your assembler instruction modifies memory in an unpredictable

fashion, add <code>memory</code> to the list of clobbered registers.  This

will cause GCC to not keep memory values cached in registers across

the assembler instruction.  You will also want to add the

<code>volatile</code> keyword if the memory affected is not listed in the

inputs or outputs of the <code>asm</code>, as the <code>memory</code> clobber does

not count as a side-effect of the <code>asm</code>.



   <p>You can put multiple assembler instructions together in a single

<code>asm</code> template, separated by the characters normally used in assembly

code for the system.  A combination that works in most places is a newline

to 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 the

assembler allows semicolons as a line-breaking character.  Note that some

assembler dialects use semicolons to start a comment. 

The input operands are guaranteed not to use any of the clobbered

registers, and neither will the output operands' addresses, so you can

read and write the clobbered registers as many times as you like.  Here

⌨️ 快捷键说明

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