Linux内核编程(一)-----------AT&T汇编语法格式

写在前面:又是一个新的系列,学习的过程就是成长的过程,重要的是坚持,当然跟之前一样,也是一边学习一边整理总结。用一段在某篇文章看到话来开始这个系列吧:那些跑得更远的人,都是因为别人放弃时,他们还在跑。 所以就这么一直勇敢地跑下去吧。 毕竟,你是一个,连放弃,也做不到的人啊。QQ:993650814

第一篇主要介绍几个常用的汇编语法,后面会用一个嵌入式汇编例子来讲解通常汇编在C中内嵌的用法。

 

正文:

1、寄存器的引用
   引用寄存器要在寄存器前加%,如 mov %eax , %ebx        //把寄存器eax中的内容放到ebx寄存器中去

2、操作数顺序: 从源(左)到目的(右),例如上述,eax是源,ebx是目的。

3、常数/立即数的格式
  立即数要在前面加$,如mov $4,%ebx
  符号常数直接引用,如 mov value, %ebx
  引用符号地址要在符号前加$,如 mov $value, %ebx

4、操作数的长度

  操作数的长度用加在指令后的符号表示,
  b(byte,1个字节) w(word,2个字节) l(long,4个字节),如 mov w %ax, %bx  //把ax寄存器的内容复制到bx寄存器中去,长度2Byte
  
5、嵌入式汇编语句: _asm_("asm statements":outputs:inputs:registers-modified); 
     asm statements: 加载的代码 汇编语句,可以有多条,会变语句后面用\n\t结束
     outputs:inputs:registers-modified :这三者都是可选项。
     outputs:输出寄存器
     inputs:输入寄存器,
     registers-modified:被修改的寄存器
     "a"、"b"、"c"、"d"分别表示eax、ebx、ecx、edx
     "S"和"D",代表esi、edi
     "r":任何寄存器
    "0":与上一个寄存器使用同一个寄存器
 

6、example:

   代码中对例子中的汇编每行语句都会进行详细分析:

int main(void)
{
	int a1 = 10,b1 = 0;
	
	_asm_("movl %1, %%eax;\\n\r"
	"movl %%eax,%%ecx;"
	:"=a"(b1)              
	:"b"(a1)
	:"%eax");
	
	printf("a1 = %d,b1 = %d\n",a1,b1);
	
/*
	这段汇编代码中,先看参数部分:
	1、输出部分:"=a"(b1)  输出的eax寄存器的内容给了b1;
	2、输入部分:"b"(a1)   把输入的a1放到了ebx寄存器中; 即 ebx = a1 =10;
	3、会改变的部分:"%eax"    eax寄存器会被改变
	再来看代码部分
	1、"movl %1, %%eax;\\n\r" 在这段代码中, %0代表 "=a"(b1),%1代表 "b"(a1),%2代表 "%eax",
		其他代码部分以此类推。
		所以这段代码的意思:将ebx的内容给了eax即eax的内容成了10;
	2、"movl %%eax,%%ecx;" :这段代码的意思:将eax寄存器的内容放到了ecx中。
	
	整体分析:
	输出的寄存器eax的内容是10;
	
	所以打印结果为:a1 = 10,b1 = 10
	
*/
	
	return 0;
}

另外,还有一处细节需要补充一下,代码中寄存器前面都有两个%%例如"movl %%eax,%%ecx;",为什么是两个%呢?

gcc编译器在编译的时候会自动拿掉一个%,而寄存器引用的时候需要%,所以这里寄存器前面都是两个%。

 

 

 

你可能感兴趣的:(Linux内核编程)