To: Basic inline assembly knowledge

Source: Internet
Author: User
Tags processing instruction

Basic inline assembly knowledge
Author: Shi Xue

I have read several articles about assembly languages by Sun yuan and other senior colleagues for a few days. As a result, I checked the 98 version of msdn and found several articles about the basis of inline assembly. The index word is ASM. It is not too difficult to talk about it, so I tried to write it down and paste it here.

I. Overview of inline assembly

In the Visual C ++ 6.0 compiler, inline assembly can use all intelease processor instruction sets. In addition, pseudo commands can be set up for the target processor to implement the additional command function. Inline assembly can use the expressions allowed by the MASM compiler. Some of these expressions can be used to perform operations on a single precision value through a combination of operators and operands.

Although inline assembly can access data variables and class objects in C/C ++, it is impossible to define data and objects through MASM commands and operators. In particular, you cannot use dB, DW, DD, DQ, DT, DF, and other definition commands as well as DUP and this operators. The structure record in the Assembly is not available either. Inline assembly does not support directives struc, record, width, and mask commands. However, one _ emit macro instruction can be used in inline assembly. It is similar to the DB instruction in MASM. It can define one byte type in the region, although it can only define one byte at a time, however, you can use it to define a string. See the example below:

#define randasm __asm _emit 0x4A __asm _emit 0x43 __asm _emit 0x4B …__asm {     randasm}

Although inline assembly does not support many commands in MASM, it supports even and align commands. They are used in assembly commands that require align labels to specify the demarcation line.

Inline assembly cannot be a macro assembly program. You cannot use macro definition commands and macro operators in MASM. However, inline assembly can use the pre-processing commands in C/C ++ to define macros.

When processing segments, you can only use registers instead of passing names, because this is illegal in inline assembly. And the segments must use registers explicitly, such as es: [BX].

In inline assembly, the length, size, and type operators can be used to measure the length of variables and types. You can use them to obtain the length of variables and types in C/C ++:

* The length operator can return the number of elements in a variable array. If the return value is 1, this is not a variable array.

* The size operator can obtain the total length of a variable and type. This value can also be obtained from the length and type product.

* The type operator can obtain the length of a variable and type. Different from the size operator, if the variable name is an array, the length of a single element in the array is added.

For details, see the following table:

_ ASM C Size
Length arr Sizeof (ARR)/sizeof (ARR [0]) 8
Size arr Sizeof (ARR) 16
Type arr Sizeof (ARR [0]) 2

Programs that contain inline assembly can be compiled using the/Zi option for code-level debugging. In this way, you can set breakpoints in both the C/C ++ program segment and the inline assembly segment. If you use the/Fas option to allow mixed assembly and C/C ++ program debugging, then you can see a collection of code mixed with the Assembly and source program.

The Visual C ++ compiler allows you to use the MMX Instruction Set of an Intel processor in an inline assembler. However, if you use the MMX Instruction Set compiler, a warning is reported. For more information, see the msdn web site.

Ii. usage instructions on inline assembly:

Because inline assembly does not require compilation and linking, it is more convenient than an assembly program. Because it can access the variables and functions in C/C ++, it can better integrate with your C/C ++ code. Inline assembly can be programmed in the following aspects:

* Compile functions in assembly language.
* Use an assembly language to generate a code segment for speed optimization.
* You can directly use the assembly language to access the hardware.
* Write the on-site protection and recovery code (PROLOG and epilog Code) for the naked function call)

If you plan to run programs on different machines, you should place specific assembly code for different machines. Because inline assembly has certain machine uniqueness, it does not fully support macros and Data Types in all masms.

VC does not support the ASM keyword in C ++, so you need to use the _ ASM (two underscores) keyword to compile your inline assembly code.

You can use this keyword to compile an Inline code segment, such:

__asm{   mov al, 2   mov dx, 0xD007   out al, dx}

You can also write only one line of Inline code, such:

__asm mov al, 2__asm mov dx, 0xD007__asm out al, dx

The above two sections of code are synonymous. However, the first method is advantageous (advantages ?), It can be significantly different from the C source code, and avoid repeated input of unnecessary _ ASM keywords. In the inline assembly code segment, the following C language elements can be applied:
* Symbol, including the jump label, variable name, and function name. (The C/C ++ symbol must be within its domain name .)
* C/C ++ constants, including const symbolic constants and constants in the shared body (Enum)
* Macros and preprocessing expressions.
* C/C ++ style annotations ,//,/*,*/
* Type name
* Type name defined by typedef

3. Use the C Operator in inline assembly code

C/C ++ proprietary operators cannot be used in inline assembly, such as: <, although some operators are used in both MASM and C, such as * operators. However, in inline assembly, it is preferentially interpreted as an assembly operator. For example, brackets in C are used to access the elements of the array. C interprets it as the first address + the length of a single element * the sequence number of the element. In inline assembly, it is interpreted as the number defined in the first address + square brackets. Is the byte offset of an address. This should be noted in programming. The following code is incorrect.

Int array [10] ;__ ASM mov array [6], 0; expected to achieve the array [6] = 0 Function in C, but this is wrong.

The correct code is as follows:

__asm mov array[6 * TYPE int], 0 ; array[6] = 0;

Use the C/C ++ symbol in the inline assembly (as described above, the symbol includes the constant name, variable name, function name, and jump label). Pay attention to the following points:
* The C/C ++ symbol must be within its domain name.
* Generally, only one C/C ++ symbol can appear in an Assembly statement. Multiple C/C ++ symbols can be used in length, type, and size expressions.
* Like the C language, you must explicitly declare a function before calling a function in inline assembly. Otherwise, the compiler reports an error.
* Note that the C/C ++ symbols with the same Reserved Words in MASM cannot be used in inline assembly.
* Note that classes, structs, and shared objects in C/C ++ are not directly used in inline assembly.
The following example shows how to use the C/C ++ symbol.
If C has defined a variable VAR, inline assembly can access the variable as follows:

_ ASM mov eax and VAR; assign the value in the variable VAR to the eax register.

If there is a struct first_type and an instance HAL:

struct first_type{   char *weasel;   int same_name;} hal;

When accessing the Hal object, it must be as follows:

_ ASM {mov EBX, offset Hal; get the first address of the Hal object mov ECx, [EBX] hal. same_name; with the same_name offset value, you can access the member same_name mov ESI, [EBX] hal. weasel; plus the weasel offset value .}

The following is an example of how to implement a function in inline assembly:

# Include <stdio. h> int power2 (INT num, int power); void main (void) {printf ("3 times 2 to the power of 5 is % d/N ", /power2 (3, 5);} int power2 (INT num, int power) {_ ASM {mov eax, num; get the first parameter mov ECx, power; obtain the second parameter SHL eax, Cl; eax = eax * Cl} // In the function, the returned value is transferred back by eax. (By the way, what is the difference between ax and eax? Is it the same ?)}

Because no return exists in the inline function, the compiler reports a warning in the preceding example. Fortunately, unlike Java, a single return cannot be compiled. You can use macro # pragma warning to turn off the warning tool. In pascall functions, stack reset is the responsibility of the function, rather than the caller. In the preceding example, the Assembly function is embedded in the C function. At the exit of the C function, the C compiler automatically adds the re-stack command without having to write it on its own. This will lead to system confusion. In the inline assembly, jump commands (including conditional jumps) can jump to all the places where the C language goto can go. Goto can also jump to the label defined in inline assembly, for example:

Void func (void) {goto c_dest;/* Legal: correct case */goto c_dest;/* error: Incorrect case is distinguished in lower case of C. */Goto a_dest;/* Legal: correct case */goto a_dest;/* Legal: Incorrect case */_ ASM {JMP c_dest; Legal: correct case JMP c_dest; Legal: incorrect case JMP a_dest; Legal: correct case JMP a_dest; Legal: Incorrect case a_dest:; _ ASM label} c_dest:/* C label */return ;}

In addition, when naming a tag, try to avoid duplicate names with the internal or used label names in C. If that happens, a catastrophic program error will occur. Therefore, it is best to check whether the name has been used. When referencing a function, pay attention to the parameter Stack from right to left. For example, if a function is int CADD (int A, int B), it should be called as follows:

_ ASM {mov eax, 2; push; parameter B equals 2 mov eax, 3; push; parameter A equals 3 call CADD; call the CADD function mov result, eax; the return values of all functions are stored in eax. Therefore, result is equal to 5}

Note that inline assembly cannot call overload functions, because the names of the overloaded functions are different from those of the original functions. So if you need to call the function (I remember there is an article about the overload function in vckbase), do not define the overload function, and the C ++ function must be defined using the extern "C" keyword. Because the pre-processing instruction # define in C is a character replacement, you can use # define to define an assembly macro, for example:

#define PORTIO __asm      //* Port output */         /{                         /   __asm mov al, 2        /   __asm mov dx, 0xD007   /   __asm out al, dx       /}

The above is the basic usage description of inline assembly. Because my English is not very good, the articles I have written are not continuous. Most of them are what I have said, and I may translate them incorrectly. Please forgive me. The following is an example of a class and struct written by myself:

# Include <iostream. h> struct mydata {int nmember1; int * lpmember2 ;}; void main () {mydata sample; _ ASM // This is the value assigned to the member variable {mov eax, 12; moV sample. nmember1, eax;} cout <sample. nmember1 <Endl; _ ASM // This is a member pointer value {Lea eax, sample. nmember1; MoV sample. lpmember2, eax;} cout <* sample. lpmember2 <Endl; _ ASM // This is a value for the variable pointed to by the pointer {mov EBX, sample. lpmember2; MoV eax, 5; MoV [EBX], eax;} cout <sample. nmember1 <Endl ;}

However, the call to member functions is still unsuccessful. Please help solve this problem. Thank you.

Latest comment [Post comment] [Article Contribution] View All comments and recommend them to friends
You cannot use offset to get the offset of the struct object. Lea can also.
It seems that the access to the struct does not have to take the offset address first.
(Lyzlyz_2004 was published on 21:01:00)
 
It is clearly stated on msdn that inline assembly cannot call member functions (myh9999 was published on 16:31:00)
 
Http://tongtian.net/cgi-bin/topic.cgi? Forum = 6 & topic = 44 & show = 0 (PRO/E posted on 14:07:00)
 
Well written, it seems that my bricks are not flushed ..........
A big piece of jade .........
If you want to learn inline assembly, you should read more .......
I have read it several times! Pai_^
Sun yuan (published by gamebaby at 9:29:00, 2002-12-3)
 
I have the question of how to implement my own defined interrupt service programs in inline assembly? (I found that proc and endp are illegal in VC, so I cannot implement the above problem) (c_jiang was published on 20:59:00)
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.