C language Embedded Assembly

Source: Internet
Author: User
Tags processing instruction

In Embedded Assembly, the C language expression can be specified as the operand of the assembly instruction, and you do not have to worry about how to read the value of the C language expression into which register, and how to write the calculation result back to the C variable, you only need to tell the program the ing between the C language expression and the assembly instruction operand, GCC will automatically Insert the code to complete the necessary operations.

1. Simple Embedded Assembly
Example:
_ ASM __
_ Volatile _ ("hlt ");
"_ ASM _" indicates that the subsequent code is embedded assembly, and "ASM" is the alias of "_ ASM. "_ Volatile _" indicates that the compiler should not optimize the code and the subsequent commands
Keep it as it is, and "volatile" is its alias. The brackets contain Assembly commands.

In Embedded Assembly, the C language expression can be specified as the operand of the assembly instruction, and you do not have to worry about how to read the value of the C language expression into which register, and how to write the calculation result back to the C variable, you only need to tell the program the ing between the C language expression and the assembly instruction operand, GCC will automatically Insert the code to complete the necessary operations.

1. Simple Embedded Assembly
Example:
_ ASM __
_ Volatile _ ("hlt ");
"_ ASM _" indicates that the subsequent code is embedded assembly, and "ASM" is the alias of "_ ASM. "_ Volatile _" indicates that the compiler should not optimize the code and the subsequent commands
Keep it as it is, and "volatile" is its alias. The brackets contain Assembly commands.

2. Example of Embedded Assembly
To use embedded assembly, you must first compile the assembly instruction template, then associate the C language expression with the instruction operand, And tell GCC What restrictions are imposed on these operations. For example, in the following Assembly statement:
_ ASM _ violate _ ("movl % 1, % 0": "= r" (result): "M" (input ));

"Movl
% 1, % 0 is the instruction template; "% 0" and "% 1" represent the operands of the instruction, which are called placeholders. Embedded Assembly relies on them
The language expression corresponds to the instruction operand. The instruction template is enclosed in parentheses in C language expressions. In this example, there are only two expressions: "result" and "input ".
Do not match the command operands "% 0" and "% 1". Note the order: the first c expression corresponds to "% 0", and the second expression corresponds to "% 1 ", and so on, the number of operands is up to 10.
Respectively, "% 0", "% 1 ".... "% 9" indicates. There is a string enclosed in quotation marks before each operand. The content of the string is a limitation or requirement on the operand.
The limit string before "result" is "= r", where "=" indicates that "result" is the output operand, "R" indicates that "result" needs to be associated with a general register,
First, read the value of the operand into the Register, and then use the corresponding register in the instruction, instead of the "result" itself. Of course, after the instruction is executed, you need to save the value in the register to the variable "result ".
On the surface, it seems like the command directly operates on the "result". In fact, GCC has implemented implicit processing, so that we can write less commands. The "R" before "input" indicates that this expression requires
First put a register, and then use this register in the command for calculation.
The relationship between C expressions or variables and registers is automatically handled by GCC.
What can GCC do. The limit character must match the instruction's requirements on the operand. Otherwise, the resulting assembly code may be wrong. You can change the two "R" in the above example to "M" (M indicates the operand ).
In the memory, rather than in the register), the result after compilation is:
Movl input, result
Obviously this is an invalid instruction, so the character string must match the instruction's requirements on the operand. For example, the instruction movl allows the Register to the register and counts immediately to the register, but does not allow the memory to the memory. Therefore, the two operands cannot use "M" as the delimiter at the same time.
The embedded assembly syntax is as follows:
_ ASM _ (Assembly statement template: Output part: input part: Destroy description part)
There are four parts in total: The Assembly statement template, the output part, the input part, and the destruction description part. Each part uses the ":" format. The Assembly statement template is required. The other three parts are optional, if the latter part is used, and the former part is empty, use the ":" format. The content of the corresponding part is empty. For example:
_ ASM _ volatile _ ("CLI": "Memory ")

1. Assembly statement Template
Sink
A compilation statement template consists of a sequence of Assembly statements, separated by ";", "/N", or "/n/t. The operands in the instruction can use placeholders to reference C language variables. The operands can have up to 10 placeholders.
Names: % 0, % 1 ,..., % 9. Operations expressed by placeholders in a command are always considered as long (4 bytes), but the operations applied to the command can be a word or byte.
When the operand is used as a word or byte, the default value is low or low. The Byte operation can explicitly specify whether it is a low byte or a secondary byte. Insert a letter between % and serial number. "B" indicates a low character.
Section, "H" indicates the high byte, for example, % H1.

2. Output part
The output part describes the output operands. Different operands are separated by commas. each operand descriptor consists of a limited string and a C-language variable. The limited string of each output operand must contain "=", indicating that it is an output operand.
Example:
_ ASM _ volatile _ ("pushfl; popl % 0; CLI": "= G" (x ))
The descriptor string represents the constraints on the variable, so that GCC can determine how to allocate registers based on these conditions, and how to generate the connection between the necessary code Processing Instruction operands and C expressions or C variables.

3. Input
The input part describes the input operands. Different operands are separated by commas (,). Each operand descriptor consists of a limited string, a C expression, or a C variable.
Example 1:
_ ASM _ volatile _ ("LIDT % 0": "M" (real_mode_idt ));
Example 2 (bitops. h ):
Static _ inline _ void _ set_bit (int nr, volatile void * ADDR)
{
_ ASM __(
"Btsl % 1, % 0"
: "= M" (ADDR)
: "Ir" (NR ));
}

After
The example function is to set the nth Nr bit of (* ADDR) to 1. The first placeholder % 0 and C
The language variable ADDR corresponds, and the second placeholder % 1 corresponds to the C language variable Nr. Therefore, the Assembly statement code above is equivalent to the pseudocode below: btsl NR,
ADDR. The two operands of this command cannot be all memory variables. Therefore, the qualified string of NR is specified as "ir ",
Associated with the immediate number or register, so that only ADDR is the memory variable in the two operands.

4. Restricted characters
4.1. Restricted Character List
There are many types of restricted characters, some of which are related to the specific architecture. Here, only the commonly used qualified characters and some common qualifiers that may be used in i386 are listed. They are used to indicate how the compiler processes the relationship between the subsequent C language variables and the instruction operands.

CATEGORY qualifier description
General Register "A" puts the input variable into eax
Here is a question: what if eax has been used?
In fact, it is very simple: because GCC knows that eax has been used, it assembles the code in this section
Insert a statement pushl % eax at the beginning of, save the eax content to the stack
Then add a statement popl % eax at the end of the Code to restore the content of eax.
"B" puts the input variable into EBX
"C" puts input variables into ECx
"D" puts the input variable in edX
"S" puts the input variable into ESI
"D" puts the input variable into EDI
"Q" puts the input variables into one of eax, EBX, ECx, and EDX.
"R" puts the input variables into General registers, that is, eax, EBX, ECx,
One of edX, ESI, and EDI
"A" combines eax and EDX into a 64-bit register (use long longs)

Memory "M" memory variable
The "O" operand is a memory variable, but its addressing method is offset type,
That is, base address addressing, or base address plus address change addressing
The "v" operand is a memory variable, but the addressing method is not an offset type.
The "" operand is a memory variable, but the addressing mode is auto increment.
The "p" operand is a valid memory address (pointer)

Register or memory "G" to put the input variable into one of eax, EBX, ECx, and EDX
Or as a memory variable
The "X" operand can be of any type.

Instant count
Immediate number between "I" and "31" (for 32-bit displacement instructions)
Immediate number between "J" and "63" (for 64-bit displacement instructions)
Immediate number between "N" and "255" (used for the out command)
"I" immediate count
"N": immediate number. Some systems do not support immediate numbers except words,
These systems should use "N" instead of "I"

Matches "0", indicating that the operands restricted by it match a specified operand,
"1"... that is, the specified operand, for example, "0"
"9" describes the operands of "% 1", so the reference of "% 1" is actually
Is the operand of "% 0". Note that the 0-9 and
The difference between "% 0"-"% 9" in the command. The former describes the operands,
The latter represents the operands.
& The output operations cannot use registers that are the same as the input operations.

Operand type "=" the operand is only written in the instruction (output operand)
The "+" operand is read/write type in the instruction (input/output operand)

Floating Point "F" floating point register
"T" the first floating point register
"U" second floating point register
"G" Standard 80387 floating point constant
% This operand can be switched to the next operand
For example, the two operands of addl can exchange order.
(Of course, neither of the two operands can be an immediate number)
# Partial comments. All letters from this character to the comma after it are ignored
* Indicates that if a register is selected, the subsequent letters are ignored.

5. Damage description
The destroy descriptor is used to notify the Compiler which registers or memory are used. It is composed of comma-separated strings. Each string describes a situation, generally the register name; in addition to registers, there is also "Memory ". For example, "% eax", "% EBX", and "Memory.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.