Assembly languages are widely used, such as increasing program speed, reducing memory needs, and controlling hardware. To embed assembly language instructions directly in steps C and C ++ source code without additional Assembly sets and links, you can use inline assembly. The Embedded Assembler is a built-in compiler, so you do not need a separate assembler, such as Microsoft's Macro Assembler (MASM ).
Note:
The Program for inline assembly code is not completely portable to other hardware platforms. Avoid using inline assembly if you are designing portability.
The Android and x64 processors do not support inline assembly.
The following topics describe how to use visual c/C ++ inline assembly and x86 processors:
; ========================================================== =
1. Embedded Assembler Overview
2. _ ASM syntax
3. Miscellaneous
; ========================================================== =
1. Embedded Assembler Overview
The Embedded Assembler allows you to embed assembly language instructions in steps C and C ++ source code programs without additional Assembly sets and links. Built-in inline assembly in the compiler-you don't need a separate assembler, such as Microsoft's Macro Assembler (MASM ).
Inline assembly does not require separate assembly and link steps because it is more convenient than a separate assembly program. Inline assembly code can use the names of any C or C ++ variables or functions within the scope, so it is easy to integrate them into your program's C and C ++ code. It can mix assembly code with C and C ++ statements, because it can be troublesome or impossible to separate tasks in C or C ++.
The _ ASM keyword calls inline assembly and can be displayed in a valid place of C or C ++ code. It is meaningless. It must follow the assembly instructions. A group of commands are enclosed in braces or empty parentheses. The word "_ ASM block" here refers to any instruction or a group of instructions.
The following code is a simple _ ASM block placed in parentheses. (The code is a sequence of custom function Prolog.
// Asm_overview.cpp
// Processor: x86
Void _ declspec (naked) Main ()
{
// Naked functions must provide their own Prolog...
_ ASM {
Push EBP
MoV EBP, ESP
Sub ESP, _ local_size
}
//... And epilog
_ ASM {
Pop EBP
RET
}
}
Alternatively, you can put _ ASM before each assembly instruction:
_ ASM push EBP
_ ASM mov EBP, ESP
_ ASM sub ESP, _ local_size
Since the _ ASM keyword is a statement separator, you can also place assembly commands on the same line:
_ ASM push EBP _ ASM mov EBP, esp _ ASM sub ESP, _ local_size
; ========================================================== ======================================
2. _ ASM syntax
The following syntax:
_ ASM Assembly Command [;]
_ ASM {instruction set ticket} [;]
Syntax
--------------------------------------------------------------------------------
ASM statement:
_ ASM Assembly command; select
_ ASM {instruction set ticket}; select
If the _ ASM keyword without parentheses is used, the rest of the line is an assembly language statement. If braces are used, this means that each line between braces is an assembly language statement. With the compatibility of previous versions, _ ASM is synonymous with _ ASM.
The _ ASM keyword is a statement separator, because you can describe the Assembly on the same line.
Set breakpoints
_ Asm int 3
If you want to import a breakpoint in your code and compile it into msil, use the _ debugbreak function.
Example
--------------------------------------------------------------------------------
The following code snippet is a simple _ ASM block enclosed in braces:
_ ASM {
MoV Al, 2
MoV dx, 0xd007
Out dx, Al
}
Alternatively, you can put _ ASM before each assembly instruction:
_ ASM mov Al, 2
_ ASM mov dx, 0xd007
_ ASM out dx, Al
Because the _ ASM keyword is a statement separator, you can also place assembly commands on the same line:
_ ASM mov Al, 2 _ ASM mov dx, 0xd007 _ ASM out dx, Al
All three examples generate the same code, but the first style (enclosed _ ASM block in braces) has some advantages. Braces specify C or C ++ code for separate assembly code, and avoid unnecessary duplication of the _ ASM keyword. Braces can also prevent ambiguity. To place the C or C ++ statement on the same line as the _ ASM block, the block must be enclosed in braces. Without braces, the compiler cannot tell the Assembly Code site where the C or C ++ statements start. Finally, because the text in braces has the same format, as a common MASM text, it is easy to cut and paste the text in the existing MASM source code file.
Unlike braces in C and C ++, braces _ ASM do not affect the range of variables. You can also nest block _ ASM. nesting does not affect the range of variables.
; ========================================================== ======================================
3. Miscellaneous
Inline assembly calls C function library
// Inlineassembler_calling_c_functions_in_inline_assembly.cpp
// Processor: x86
# Include <stdio. h>
Char format [] = "% S % s/n ";
Char Hello [] = "hello ";
Char world [] = "world ";
Int main (void)
{
_ ASM
{
MoV eax, offset world
Push eax
MoV eax, offset hello
Push eax
MoV eax, offset format
Push eax
Call printf
// Clean up the stack so that main can exit cleanly
// Use the unused register EBX to do the cleanup
Pop EBX
Pop EBX
Pop EBX
}
}
// Printf (format, Hello, world );
The example pushes pointers to world, hello, and format, in that order, and then CILS printf.
Jump tag
Void func (void)
{
Goto c_dest;/* Legal: correct case */
Goto c_dest;/* error: Incorrect 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;
}
Int main ()
{
}
It is best not to use the function name in the C function library as a label, such:
; Bad technique: using library function name as label
JNE exit
.
.
.
Exit:
; More _ ASM Code follows
Because exit is the name of a C library function, this code might cause a jump to the exit function instead of to the desired location.
As in MASM programs, the dollar symbol ($) serves as the current location counter. it is a label for the instruction currently being assembled. in _ ASM blocks, its main use is to make long conditional jumps:
JNE $ + 5; next instruction is 5 bytes long
JMP farlabel
; $ + 5
.
.
.
Farlabel:
Two Methods of assembly:
; Power. ASM
; Compute the power of an integer
;
Public _ power2
_ Text Segment word public 'code'
_ Power2 proc
Push EBP; save EBP
MoV EBP, esp; move ESP into EBP so we can refer
; To arguments on the stack
MoV eax, [EBP + 4]; get first argument
MoV ECx, [EBP + 6]; get second argument
SHL eax, Cl; eax = eax * (2 ^ cl)
Pop EBP; restore EBP
RET; return with sum in eax
_ Power2 endp
_ Text ends
End
// ================================================ =====
// Power2_inline_asm.c
// Compile with:/ESCs
// Processor: x86
# Include <stdio. h>
Int power2 (INT num, int power );
Int main (void)
{
Printf_s ("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 first argument
MoV ECx, power; get second argument
SHL eax, Cl; eax = eax * (2 to the power of Cl)
}
// Return with result in eax
}
Directly execute commands
The _ emit pseudo doinstruction is similar to the DB directive of MASM. you use _ emit to define a single immediate byte at the current location in the current text segment. however, _ emit can define only one byte at a time, and it can only define bytes in the text segment. it uses the same syntax as the int instruction.
# Define randasm _ ASM _ emit 0x4a _ ASM _ emit 0x43 _ ASM _ emit 0x4b
.
.
.
_ ASM {
Randasm
}
Use of Multimedia Instruction Sets
The Visual C ++ compiler allows you to use intel's MMX (Multimedia extension) Instruction Set in the inline extends er. the MMX instructions are also supported by the debugger disassembly. the compiler generates a warning message if the function contains MMX instructions but does not contain an Emms instruction to empty the multimedia state. for more information, see the Intel web site.
The length, size, and type operators have a limited meaning in inline assembly. they cannot be used at all with the DUP operator (because you cannot define data with MASM directives or operators ). but you can use them to find the size of C or C ++ variables or types:
The length operator can return the number of elements in an array. It returns the value 1 for non-array variables.
The size operator can return the size of a C or C ++ variable. A variable's size is the product of its length and type.
The type operator can return the size of a C or C ++ type or variable. If the variable is an array, type returns the size of a single element of the array.
For example, if your program has an 8-element int array,
Int arr [8];
_ Asm c size
Length arr sizeof (ARR)/sizeof (ARR [0]) 8
Size arr sizeof (ARR) 32
Type arr sizeof (ARR [0]) 4
Reference: http://msdn.microsoft.com/zh-cn/library/4ks26t93 (V = vs.90)