Inline Assembly within function Syntax

grammar

__asm [volatile] (
    "<assembly string>"
    [ : <output operands>
    [ : <input operands>
    [ : <clobbers> ] ] ]
    );

Examples

int add(int a, int b) {
    int result;
    __asm(
    "qadd %[result], %[lhs], %[rhs]"
    : [result] "=r"(result)
    : [lhs] "r"(a), [rhs] "r"(b)
    );
    return result;
}

Assembly String

"qadd %[result], %[lhs], %[rhs]"

Is a piece of assembly code, this example uses qadd do addition, the format is qadd

QADD{cond} {Rd}, Rm, Rn

I.e.% [result] indicates Rd register (result),% [lhs] represents a register Rm (addend),% [rhs] Rn represents a register (addend)

Special note is to register starting with% (% [Result]) was a template string (template), the compiler allocates registers to the result, lhs, rhs, and replace% [result],% [lhs],% [ rhs]

output operands

Output operands, for obtaining execution results Assembly String, [result] "= r" (result) is an operand, a plurality of operand separated by commas. The specific format is

[<name>] "<constraint>" (<value>)
Children Explanation
<name> In this example the result string middle finger, and it is Assembly String% [result] corresponds.
The compiler selects the appropriate register to the replaced.
<constraint> This Example middle = r, specifically refer to a constraint.
<value> This Example middle variable int result.

input operands

The input operands, for some variables C / C ++ value to the register. [lhs] "r" (a ), [rhs] "r" (b) shows a value of the variable a and b, respectively, to the register lhs and rhs. Such assembly code to calculate a + b and how much.
And the same format of the input operands, a plurality of operands separated by commas, the format of each operand:

[<name>] "<constraint>" (<value>)
Children Explanation
<name> This embodiment lhs and rhs middle strings, and it is Assembly String% [lhs]% and [rhs] corresponds.
The compiler selects the appropriate register to the replaced.
<constraint> This Example middle = r, specifically refer to a constraint.
<value> This embodiment int a variable middle and int b.

clobbers

Clobber list English translation "list of wastes", which in this case is the register does not want assembly code used as output and input operands operands, then it will be listed in these registers, also separated by commas.
For example, one of the registers in the compilation, saving the temporary variable, if this time is specified as input or output, the problem may occur. As an example of the above can be rewritten as

int add(int a, int b) {
    int result;
    __asm(
    "mov r5, %[lhs]\n"
            "qadd %[result], r5, %[rhs]"
    : [result] "=r"(result)
    : [lhs] "r"(a), [rhs] "r"(b)
    : "r5"
    );
    return result;
}

This time, r5 as a temporary register to hold the value of lhs, rhs values and then added, so if you do not specify clobbers words, rhs and r5 in case of allocating the same register, then the value of rhs will be lost, the end result It will be a + a a.
In addition to an outer setting register, clobbers may also be provided two further special settings, "cc" and "memory" ,.

Children Explanation
cc
memory

volatile

Whether to allow the compiler to optimize the assembly code, plus volatile optimization is not allowed.
.

Reproduced in: https: //www.jianshu.com/p/dff6fe17a8be

Guess you like

Origin blog.csdn.net/weixin_33831196/article/details/91244444
Recommended