分类:
2008-06-16 15:46:21
寄存器命名:寄存器名称有 % 前缀。即,如果必须使用 eax,它应该用作 %eax。
操作数的顺序:与intel 相反,可见仇恨有多大~~
操作数大小:根据操作数是字节 (byte)、字 (word) 还是长型 (long),指令的后缀可以是 b、w 或 l.这并不是强制性的;但为了自己好也要带上啊是不是?以后还要看得嘛!
立即操作数:通过使用 $ 指定直接操作数。
间接内存引用 :任何对内存的间接引用都是通过使用 ( ) 来完成的。
内嵌汇编语法:
asm (
assembler template
: output operands (optional)
: input operands (optional)
: list of clobbered registers
(optional)
);
例子:
int count=1;
int value=1;
int buf[10];
void main()
{
asm(
cld nt
rep nt
stosl
:
: c (count), a (value) , d (buf[0])
: %ecx,%edi );
}
其中符号c(count)指示要把count的值放入ecx寄存器
类似的还有:
a eax
b ebx
c ecx
d edx
S esi
D edi
q(从eax,ebx,ecx,edx中自动分配)
r(从eax,ebx,ecx,edx,esi,edi自动分配)
g (eax,ebx,ecx,edx或内存变量)
a 把eax和edx合成一个64位的寄存器(use long longs)
数字%n的用法:数字表示的寄存器是按照出现和从左到右的顺序映射到用r或q请求
的寄存器。
如果强制使用固定的寄存器的话,如不用%1,而用ebx,则注意要使用两个%,因为一个%的语法
已经被%n用掉了.
以下是我写的例子,你看看就明白了,很容易的,但是对你理解以上东西很有帮助。
*************************************************************************
//andl
int main()
{
int in=0x12345678;
asm(
"andl $-16,%0 \n"
:
:"m"(in)
);
printf("the %x is %x after andl\n ",in);
}
************************************************************************
//cmpl
int main()
{
int in=100;
char out;
asm(
"cmp $101,%1\n"
"lahf\n"
"movb %%ah,%%al\n"
: "=a"(out)
: "r"(in)
);
if(!(out&0x80))printf("in >=101\n");
else printf("in<101\n");
}
****************************************************************************
//lds
int main()
{
char src;
short base;
short off;
asm(
"lds %0,%%di\n"
"mov %%ds,%1\n"
"mov %%di,%2\n"
:
:"m"(src),"r"(base),"r"(off)
:"%edx","%edi"
);
printf("the base is %x\n",base);
printf("the off is %x\n",off);
}
//该程序出现段错误,是因为在保护模式下不允许写ds寄存器吗?
******************************************************************************
//neg
int main()
{
short in = 0x000f;
printf("before neg :in is %x\n",in);
asm(
"neg %0\n"
:"=r"(in)
:"0"(in)
);
printf("after neg :in is %x\n",in);
}
*********************************************************************************
//sar shr
int main()
{
int in1=-0xf00;
int in2=-0xf00;
int in3=-0xf00;
printf("in1 is %x,in2 is %x \n",in1,in2);
asm(
"sarl $8,%0\n"
"shrl $8,%1\n"
:
:"m"(in1),"m"(in2)
);
printf("in1 is %x,in2 is %x\n",in1,in2);
}
***********************************************************************************
//xchgl
int main()
{
char *p="abcd";
char *q="1234";
printf("p is %s,q is %s\n",p,q);
asm(
"xchgl %0,%1\n"
:"=r"(q)
:"m"(p),"0"(q)
);
printf("p is %s,q is %s\n",p,q);
}
***********************************************************************************
//adc
int main()
{
int in1=100;
int in2=200;
printf("in1 is %d,in2 is %d\n",in1,in2);
asm(
"movw %0,%%ax\n"
"addw %2,%%ax\n"
"movw %%ax,%0\n"
"leal %0,%%ecx\n"
"leal %2,%%edx\n"
"movw 2(%%edx),%%ax\n"
"adcw %%ax,2(%%ecx)\n"
:"=m"(in1)
:"0"(in1),"m"(in2)
);
printf("in1 is %d,in2 is %d\n",in1,in2);
}
//这个过程中用到了leal,这个指令用来取变量的地址到寄存器中,要取某个变量附近的内容时很管用。
************************************************************************************
//lea
int main()
{
char *p;
printf("the address of p is %x\n",&p);
asm(
"leal %1,%%eax\n"
"movl %%eax,%0\n"
:"=m"(p)
:"0"(p)
);
printf("the value of p is %x\n",p);
}
//将p的值取出来,放在p中,是不是让你对c语言的指针豁然开朗呢?
*************************************************************************************
//not
int main()
{
int in=0x89abcdef;
printf("the in is %x\n",in);
asm(
"notl %1\n"
:"=r"(in)
:"0"(in)
);
printf("the in is %x\n",in);
}
*************************************************************************************
//sbb
int main()
{
int in1=100;
int in2=200;
printf("in1 is %d,in2 is %d\n",in1,in2);
asm(
"movw %0,%%ax\n"
"subw %2,%%ax\n"
"movw %%ax,%0\n"
"leal %0,%%ecx\n"
"leal %2,%%edx\n"
"movw 2(%%edx),%%ax\n"
"sbbw %%ax,2(%%ecx)\n"
:"=m"(in1)
:"0"(in1),"m"(in2)
);
printf("after in1-in2-->in1\n");
printf("in1 is %d,in2 is %d\n",in1,in2);
}
**************************************************************************************
//xlat
char str[10]="abcdefghi";
char p;
int main()
{
asm(
"movl %1,%%ebx\n"
"movb $2,%%al\n"
"xlat\n"
:"=a"(p)
:"r"(str)
);
printf("%c\n",p);
}
*************************************************************************************
//lahf
int main()
{
char out = 0xff;
asm(
"mov $3,%%bx\n"
"sub $1,%%bx\n"
"lahf\n"
"movb %%ah,%%al\n"
:"=a"(out)
:
);
printf("out is %x\n",out);
}
//如果你知道out的每个位的含义,就可以分析。查一下资料就行了。
**************************************************************************************
//mul
int main()
{
short in1=300;
short in2=500;
int result;
asm(
"movw %1,%%ax\n"
"mulw %2\n"
"leal %0,%%eax\n"
"mov %%ax ,(%%eax)"
"mov %%dx,2(%%ecx)\n"
:"=m"(result)
:"m"(in1),"m"(in2)
);
printf("%d * %d = %d\n",in1,in2,result);
}