Turning: Inline assembly basics

xiaoxiao2021-03-05  26

The inline assembler basics of: snow days saw the release of Sun Yuan and several articles about my dear friend assembly language, 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 put it. First, Inline Argument briefly describe 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 permitted by the MASM compiler, some of which can operate the single-enhanced value by a combination of operators and operands. Although inline assembly can access data variables in C / C and Class objects, but it is not possible to define data and objects via 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 It can still be used 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] Using the operator Length, size, and Type can be measured to measure the variables and types, you can use them to find C / C The length of the variable and type of the type: * The Length operator 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:

__asmcsizelength arrsizeof (arr) / sizeof (arr) / sizeof (arr [0]) 8Size ArrsizeOf (arr) 16TYPE ARRSIZEOF (Arr [0]) 2 The program containing the inline assembly can be compiled using the / zi option, thus the 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, regarding the specific instructions for inline assembly: Because inline assembly does not need to compile and link, it is more convenient than a compiler. 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. * Call the Naked function to write the protection site and recovery field code (ProLog and Epilog code) If you plan to run the program on different machines, then you should separately place the special assembly code of 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 decoding segment, 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 code is 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 interlaced code segment are applicable: * symbols, including jump tags, variable names, and function names. (The C / C symbols used must be within its name of the name.) * C / C constant, including constant * macros in the Const Symbolic Constant and Surgery (Enum), and pre-processing expressions. * C / C Style Note, //, / *, * / * Type * TypeDef defined type 3, using C / C proprietary in the internal co-editing code in the inner assembly code Operators, such as: <<, though, some operators are used in MASM and C, such as: * operator. 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 the wrong int Array [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 interior assembly (as mentioned earlier, symbols include constant names, variable names, function names, and jump tags) should pay attention to the following points: * C / C The symbol 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 visiting 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.

} The following is an example of how to implement 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, the system will make the system chaos. In the interpolation of the jump instruction (including condition jump), you can jump to all where the 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 CASEJMP 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, try to avoid researchers or have used tag names inside the label, if such a catastrophic program error will occur. 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, a function is int CADD (int A, int b) should be called: __ASM

{

MOV EAX, 2;

Push; parameter b is equal to 2

MOV 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 that the internal assembly cannot call the overload function because the name of the heavy load function is different from the original function name. So if you need to call, (I remember the 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 the character replacement, you can use #define to define a compilation 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 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 a piece I wrote to a class, a structure: #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.

Latest Reviews [Published Reviews] [Article Submission] See all comments Recommend to friends print

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

New Post(0)