当前位置:网站首页>GNU assembly language uses inline assembly to extend ASM

GNU assembly language uses inline assembly to extend ASM

2020-11-10 08:45:21 osc_qalfjuu8

Extended ASM format Extended asm Format :

asm The extended format of the keyword is as follows :

asm ("assembly code" : output operands : input operands : changed registers);

The extended format above consists of four parts , Each part is separated by a colon :

Assembly code: The inline assembly code using the same syntax used for the basic asm format
assembly code: The assembly code part , You can write the required inline assembly code in this section , And basic asm Format compared to , The assembly code in the extended format is different in the use of the percent sign ( We'll talk about that ), Other assembly instructions are written in the same format
Output operands: A list of registers and memory locations that will contain the output values
from the inline assembly code
Output operands : Used to specify to which register the execution result of inline assembly code needs to be output , And to which C variable
Input operands: A list of registers and memory locations that contain input values for the inline
assembly code
Enter the operands : Can be C The value of the variable is entered into the specified register , In this way, in inline assembly code , Use these registers to use C The value of the variable , there C Variables can be global variables , It can also be a local variable
Changed registers: A list of any additional registers that are changed by the inline code
The modified register : Used to indicate which registers have been modified in inline assembly code , The compiler will depend on the actual situation , Do something about these modified registers push、pop Something like that , such , Assembly code modified registers will not affect the outside C Normal execution of code
Not every part has to be set up , Suppose you don't need a second output operand , Then the output operands section can be left blank , But here's the thing , Even if the output operands are left blank , The first two colons must also be retained , Such as :asm (“assembly code” : : input operands : changed registers); The format of , in addition , If you don't need to set the modified register part , Then the last colon can be omitted , Such as :asm (“assembly code” : output locations : input operands); The format of .









 Here's how to expand asm The specific format of the input and output operands in the format .

Specifying input and output values Input and output operands :

 The format of the input and output operands is as follows :

“constraint”(variable)
among , In brackets variable Express C Global or local variables defined in the code , And in quotation marks constraint( constraint ) Is used to store variable The register or memory location of the variable value . For input operands ,constraint Will be variable The value of the variable is read to the specified register , Or use the memory location of the variable directly . For output operands ,constraint It is to store the result in the specified register first , Then set the value in the register to variable variable , some constraint( constraint ) You can also write the result directly to the memory where the variable is located .

constraint( constraint ) It's a single character , The available constraints are shown in the following table :

Constraint
Constraints Description
describe
a Use the %eax, %ax, or %al registers.
Use %eax, %ax or %al register
b Use the %ebx, %bx, or %bl registers.
Use %ebx, %bx or %bl register
c Use the %ecx, %cx, or %cl registers.
Use %ecx, %cx or %cl register
d Use the %edx, %dx, or $dl registers.
Use %edx, %dx or %dl register
S Use the %esi or %si registers.
Use %esi or %si register
D Use the %edi or %di registers.
Use %edi or %di register
r Use any available general-purpose register.
Use any general register available
q Use either the %eax, %ebx, %ecx, or %edx register.
Use %eax, %ebx, %ecx or %edx register
A Use the %eax and the %edx registers
for a 64-bit value.
Use %eax and %edx Register to store a 64 The value of a
f Use a floating-point register.
Use a floating-point register
t Use the first (top) floating-point register.
Use the first one ST0 Floating point register
u Use the second floating-point register.
Use the second ST1 Floating point register
m Use the variable’s memory location.
Memory location using variables
o Use an offset memory location.
Use a memory location with an offset value , for example : Use 4(%edi) To express EDI Add offset value 4 Memory address of , It is mainly used for accessing array elements
V Use only a direct memory location.
Use a memory location without an offset value
i Use an immediate integer value.
Indicates that the operands are immediate ( Constant integer value )
n Use an immediate integer value with a known value.
Indicates that the operand is an immediate value of a known value , In many systems , When the operands are less than 1 individual word( word ) Broad hours , You can't use it i, And should be used n To express an immediate number
g Use any register or memory location available.
Any general register or memory location can be used , Or the operands are immediate
In addition to the above constraints , For operands, there is also a constraint modifier( Constraint modifiers ), Used to indicate whether the operands are readable or writable , The available constraint modifiers are shown in the following table :







































Constraint modifier
Constraint modifiers Description
describe

  • The operand can be both read from
    and written to.
    Indicates that the operands are readable and writable , for example "+r", Before the inline assembly instruction begins , The value of the variable must be assigned to the corresponding register first ( That is the process of reading ), After executing the assembly instruction , Then write the value of the register to the variable ( The process of writing )
    = The operand can only be written to.
    Indicates that the operands are written only , for example "=r", That is to say , Just write the result to the variable , As for inline assembly instructions before execution , The value in the corresponding register can be any value , There is no need to read the value of a variable before execution .
    % The operand can be switched with the
    next operand if necessary.
    When necessary , The operands can be swapped with the next , Here is an example
    & use ‘&’ for each output operand that may
    not overlap an input
    & Modifiers are used to force the compiler to assign different registers for input and output operands
    You can refer to
    http://blog.csdn.net/bokee/article/details/7029353
    The article in the link
    In the constraint modifier above "+"、"="、"&“ These three can only be used to decorate the output operands , Cannot be used to decorate input operands , and ”%“ On the contrary , Can only be used to decorate input operands ,”%" You can refer to the following code for the usage of :













int main(int __argc, char* __argv[])
{
int __in1 = 8, __in2 = 4, __out = 3;
asm (“addl %1, %0\n\t”
: “=r”(__out)
: “%r” (__in1), “0” (__in2));
return 0;
}
In this case , Because the instruction is an addition operation , It's equivalent to an equation __out = __in1 + __in2, And it's the equation __out = __in2 + __in1 There is no difference . So use the percent sign to modify , Give Way GCC know __in1 and __in2 interchangeable , in other words GCC You can automatically change the inline assembly of this example to :







asm (“addl %1, %0\n\t”

“=r”(__out)

“%r” (__in2), “0” (__in1));
The above code example comes from :http://tieba.baidu.com/p/310375553 , In addition, in the above example %1 and %0 Wait is a place holder , The meaning of the place holder will be explained in the following introduction .

The most used one is the first "+“ And the second ”=" Modifier , For example, the following code template :

asm (“assembly code” : “=a”(result) : “d”(data1), “c”(data2));
The code template above , It means that you will data1 Value of variable read to EDX register , take data2 Value of variable read to ECX register , After the inline assembly code is executed , Will save the results to EAX register , Last ,EAX The value in will be written to result variable , It has to be here "a" Add... Before the constraint "=" Modifier , Express result Operands can write data , otherwise , Because in the absence of modifiers , The operands represent read-only ,GCC The compiler will report "output operand constraint lacks ‘=’“ Error of , That is, the constraints on the output operands are missing ”=“ Modifier . You can also use it ”+" Modifier to indicate that the output operands are readable and writable .

Using registers Expanding asm The format uses registers :

 The basics introduced in the last article asm In inline assembly format , Registers are used in the same way as in a separate assembly file , Just add a percent sign before the register name , But the extensions introduced in this chapter asm In the format , When registers are to be used in inline assembly code , You must precede the name of the register with two percent signs , for example :%%eax  Form like this , The first percent sign is used to escape the second percent sign , In this way, two percent signs can represent a common percent sign to modify eax, The reason for this is , Because % Expanding asm There are special uses in the format , It's like C In a language string "\n" In the characters "\" Characters are used for and "n" Characters together represent special line breaks, just like , A single percent sign is used together with a number to indicate the place holder mentioned below .

 Below regtest1.c The program shows how to extend asm The format uses registers :
/* regtest1.c – An example of using registers */
#include <stdio.h>

int main()
{
	int data1 = 10;
	int data2 = 20;
	int result;
	asm ("imull %%edx, %%ecx\n\t"
	    "movl %%ecx, %%eax"
	    : "=a"(result)
	    : "d"(data1), "c"(data2));
	printf("The result is %d\n", result);
	return 0;
}

In the code above , Will be data1 and data2 The values of local variables are loaded into EDX and ECX after , stay asm In the assembly code of , Would pass imull %%edx, %%ecx Instructions will be EDX and ECX A register for multiplying values , The calculation results are stored in ECX in , And then through movl %%ecx, %%eax Instructions will be ECX Output the value in to EAX in , Last EAX The value in will be written to result In local variables , So in the following C You can use... In the code printf Function to result To show the value of . Here we need to pay attention to the writing of registers , Such as :%%ecx There are two percent marks for everything , The reason has been explained above .

Reference article
https://www.zengl.com/a/201404/146.html

版权声明
本文为[osc_qalfjuu8]所创,转载请带上原文链接,感谢