在VC++中,__asm伪指令可放在汇编语句的前面或用于标记一块汇编语句
__asm pushfd // 一个语句
__asm// 一个语句块
{
pushad
//todo
popad
popfd
}
注释建议直接使用C++的注释方式,这样可以避免与C宏冲突
以下为内联汇编的特性:
1.使用任何Intel指令集中的指令
所有的interl指令集可在它的官网上查到:
http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
文档:直接打开搜索就好了
2.使用寄存器操作数
3.通过名字引用函数参数
4.可以引用在汇编语句块外面声明的代码标号和变量
5.在语句中支持使用PTR操作符
inc WORD PTR[eax]
6.使用EVEN和ALIGN伪指令以下是不能使用的特性:
1.不能使用数据定义伪指令,如DB(BYTE)和DW(WORD)等
2.不能使用汇编操作符(PTR除外)
3.不能使用STRUCT 、RECORD、WIDTH和MASK
4.不能使用宏伪指令,包括MACRO、REPT、IRC、ENDM或宏操作符(<>,!,&,%)
5.不能引用段名,但可使用段寄存器作为操作数
由于__fastcall会导致编译器使用寄存器来传递参数,最好不好同时使用__fastcall和__asm
汇编内部和外部的偏移地址可以直接取得:
可以看出直接使用mov eax,s等同于mov eax, offset s
汇编内部和外部的偏移地址都可以通过lea或offset取得
如:
char *g_char ="1234";
int _tmain(int argc, _TCHAR* argv[])
{
__asm pushfd // 一个语句
__asm// 一个语句块
{
pushad
//todo
s:
lea eax,s
mov ebx,offset g_char// 取得的是g_char这个指针的地址
popad
popfd
}
在内联汇编中可以使用LGNGTH,TYPE,和SIZE操作符,但不支持SIZEOF和LENGTHOF
LGNGTH返回数组中元素的数目
TYPE返回下列值之一
1> c/c++类型或标量变量占用的字节数,使用字节对齐规则的
2>结构使用的字节数
3>对数组而言,TYPE返回单个数组元素的大小
struct st
{
int i;
byte j;
};
st obj[3];
__asm
{
pushfd
pushad
mov eax, LENGTH obj //3
mov ebx, TYPE obj //8
mov ecx, SIZE obj //24
popad
popfd
}