Inline assembly

zhaozj2021-02-16  56

I have seen a few people such as Sun Pla Jioni on the compilation language for several days. I am very interested. So I checked the MSDN of the Check 98, which also had a few items about the inline assembly, and the index word is ASM. It is not too difficult to say, so I will write it down, and I will have it.

I. Brief introduction of inline assembly

Under the Visual C 6.0 compiler, the inline assembly can use all Intel486 processor instructions. Moreover, the target processor can establish a pseudo-instruction to implement additional instruction functions. Inline assembly can use the expression allowed by the MASM compiler, some of which can operate the single-characterized value by combining operators and operands.

Although the inline assembly can access data variables in C / C and class objects, it is not possible to define data and objects through MASM instructions and operators. In particular, you cannot define instructions and DUP and THIS operators using DB, DW, DD, DQ, DT, and DF. The structural records in the assembly are not available. Inline assembly does not support Directives Struc, Record, Width, and Mask instructions. However, in the interior assembly, you can use a _emit macro, which is similar to the DB instruction in the MASM, which can define a byte type in this area, although it can only define one byte each time, but Can you use it to define a string, see example:

#define randasm __asm ​​_emit 0x4a __asm ​​_emit 0x43 __ASM _EMIT 0X4B

...

__ASM

{

Randasm

}

Although inline assembly does not support many instructions in MASM, it supports Even and Align instructions. They are used in assembly instructions that need to use Align Labels to specify the boundary line.

Inline assembly cannot be a macro assembly, you can't use macro definition instructions in MASM and macro. However, inline assembly is a pre-preserssion instruction in C / C to define macros.

When processing segments, you can only use registers, not through the name, because this is illegal in the inner assembly. And the paragraph must explicitly use the register, such as: ES: [BX].

Inline assembly use operator Length, size, and Type can be measured for the length of the variable and type, you can use them to find the length of the variables and types in C / C :

* Length operators can return the number of elements in a variable array, if returned to 1 means this is not a variable array.

* The Size operator can obtain a total length of a variable and type. This value can also be obtained from Length to Type.

* The Type operator can obtain a variable and type length, which is different from size, if the variable name is an array, returns the length of the individual elements in this array.

Please see the following table for details:

__ASM

C

Size

Length Arr

Sizeof (arr) / sizeof (Arr [0])

8

SIZE ARR

Sizeof (Arr)

16

TYPE ARR

Sizeof (Arr [0])

2

Programs containing inline assembly can be compiled using / zi options to make code-level debugging work. In this way, you can set a breakpoint in the C / C block and the inner linked section, if you use the / FAS option to allow hybrid assembly to the C / C source program debugging mode, then you can see mixing compilation and The code collection of the source program.

The Visual C compiler allows you to use the Intel processor's MMX instruction set in the inner assembly. However, if you use the MMX instruction set compiler, warnings. For more information, see the MSDN's Web site.

Second, the specific instructions for the inline assembly:

Because inline assembly does not need to compile and link, it is more convenient than one assembler. Since it is able to access variables and functions in C / C , it can be more integrated with your C / C code. Inline assembly can be programmed in the following aspects: * Write functions with assembly language.

* Use assembly language to generate speed optimization code segments.

* Use assembly language to access hardware directly.

* Writing prolog and epilog code for "Naked" Calls. (How to turn this sentence?)

If you plan to run the program on different machines, then you should separately place the special assembly code for different models. Because inline container has a certain machine specificity, it does not fully support macros and data types in all MASMs.

The VC does not support the ASM keyword in C , so you need to use the __asm ​​(two underscore) keywords to write your inline assembly code.

You can use this keyword to write an inline document, such as:

__ASM

{

MOV Al, 2

Mov DX, 0xD007

Out Al, DX

}

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

__ASM MOV Al, 2

__ASM MOV DX, 0xD007

__ASM OUT Al, DX

The above two codes are synonymous. But the first way is better (Advantages?), Which can be distinguished from C source code, and avoid repeating input unnecessary __asm ​​keywords.

The following C language elements below in the interlacing collection segments are applicable:

* Symbols, including jump tags, variable names, and function names. (The C / C symbols used must be within the name of the name.)

* C / C constant, constant in constant constant constants and interact (enum)

* Macro and pre-processing expressions.

* C / C Note, //, / *, * /

* Type name

* TypedEf defined type name

Use C operators in the internal assembly code

C / C proprietary operators, such as: <<, although, some operators are used in MASM and C, such as * operators. However, the inline general assembly is prioritized as assembly operators. For example, squirrels in C are using elements for accessing arrays. C explains it as the first address single element length * element serial number. In the interior assembly, it explains it as the number defined in the first address square bracket. Is the byte offset for an address. This is to pay attention to the programming. So the following code is wrong:

Int arch [10];

__ASM MOV Array [6], 0; expects 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 C / C symbols in the interiors (as described above, symbols include constant names, variable names, function names, and jump tags) should pay attention to the following points:

* The C / C symbol used must be within its name.

* In general, a compilation statement only allows a C / C symbol. Multiple C / C symbols can be used in Length, Type, and Size expressions.

* Just like the C language, the function must be explicitly declared before the function is called in the internal joint policy. Otherwise the compiler will report an error.

* Note that those C / C symbols that are the same as those reserved in Masm cannot be used in the inline exchange.

* Note that classes, structures, and common applications in C / C are not directly used in internal cohesion.

A plural example of examples of using C / C symbols will be taken below.

If the previous C has defined a variable VAR, then the inline assembly can access this variable as follows: __ ASM MOV Eax, Var; assign the value in the variable var to the EAX register.

If there is a structural first_type and an instance HAL:

Struct first_type

{

Char * weasel;

INT SAME_NAME;

} HAL;

When accessing the HAL object, you must be as follows:

__ASM

{

Mov EBX, OFFSET HAL; get the first address of the HAL object

MOV ECX, [EBX] hal.same_name; plus the SAME_NAME offset value, you can access the member Same_name

Mov ESI, [EBX] hal.weasel; plus a Weasel offset value.

}

Below is an example of how an internal assembly implementation of a function:

#include

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; get the second parameter

SHL EAX, Cl; EAX = EAX * CL

}

/ / In the function, the return value is transmitted back by EAX. (What is the difference between AX and EAX? Is it the same?)

}

Because there is no Return in the inline function, in the above example, the compiler will report a warning. Fortunately, not like Java, less than one Return will compile. You can use macro #pragma Warning to turn off the warning. The reset of the stack in the PASCALL function is responsible for the function, not the caller. In the above example, the assembly function is completed by embedding the assembly internally in the C function. At the C function exit, the C compiler will automatically add a repit instruction without having to add it. Then it will make the system confusing.

Inline joints, jump instructions (including condition jump), you can jump to all places that C language goto can arrive. Goto can also jump to the label defined in the inline assembly, as follows:

Void Func (Void)

{

Goto c_dest; / * legal: Correct Case * /

Goto c_dest; / * error: INCORRECT CASE is different in Case. * /

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 you name the label, try to avoid researchers or have been reused with C. If you have a catastrophic program error. Therefore, it is best to check whether this name has been used when you are named.

When the reference function is referenced, you should pay attention to the stack from the right left direction of the parameters. For example, there is a function is

Int Cadd (int A, int b)

This should be called:

__ASM

{

MOV EAX, 2;

Push; parameter b is equal to 2MOV EAX, 3;

Push; parameter a equal to 3

Call CADD; call CADD function

Mov Result, EAX; all functions of all functions are stored in EAX. So, RESULT is equal to 5

}

Note Inline Deploys cannot call overload functions because the name of the heavy load function is different from the original function name. So if you want to call, (I remember there is an article about the overload function), do not define the overload function, and the C function must be defined using the Extern "C" keyword.

Because the preprocessing command #define is a character generation, you can use #define to define a mess, for example:

#define portio __ASM /

/ * Port output * / /

{/

__ASM MOV Al, 2 /

__ASM MOV DX, 0xD007 /

__ASM OUT Al, DX /

}

The above is the basic use description of the inline assembly. Because the English is not very good, so the article written is some discontinuous, and most of the words are what I said, maybe I will change the wrong place, please advise for me.

The following is an example of my own writing about classes, structures:

#include

Struct mydata

{

INT NMEMBER1;

INT * LPMEMBER2;

}

void main ()

{

Mydata sample;

__ASM // This is assigned to member variables

{

MOV EAX, 12;

Mov Sample.nmember1, EAX;

}

Cout << Sample.nmember1 << Endl;

__ASM // This is a member pointer

{

Lea Eax, Sample.Nmember1;

Mov Sample.lpmember2, EAX;

}

Cout << * Sample.lpmember2 << endl;

__ASM // This is the value assignment to the pointer.

{

MOV EBX, Sample.lpmember2;

MOV EAX, 5;

MOV [EBX], EAX;

}

Cout << Sample.nmember1 << Endl;

}

However, there is still no success for the call to the member function. Please help you solve this problem. Thank you.

Release snow

2002-11-21

转载请注明原文地址:https://www.9cbs.com/read-24717.html

New Post(0)