O、Linux内核源码由汇编和c语言组成,Linux平台的汇编语言遵照的是AT&T汇编语法,想要了解Linux内核就必须对AT&T汇编语法有一些了解,但看Linux内核的目的是了解内核的运行机制,对汇编的了解浅尝辄止便可。
一、AT&T汇编语法格式(区别于Intel)
1、引用寄存器的值
引用寄存器要在寄存器号前加%,例如:mov % eax,% ebx (Intel则不需要加%)
2、 *** 作数顺序
*** 作数的排列顺序是从源(左)到目的(右),如mov % eax(源),% ebx(目的) (Intel则是反的)
3、常数(立即数)的使用格式
使用立即数,需要在数前面加$,如mov
4
,
4,% ebx,没有
4,会默认立即数为内存地址
符号常数直接引用,如mov value,% ebx,将value的值放到ebx寄存器中
引用符号地址在符号前面加$,如mov $value,% ebx,将value的地址放到ebx寄存器中
4、 *** 作数的长度
*** 作数的长度用加在指令后面的符号来表示,b是byte,w是word(2字节16位),l是long(4字节32位)
如命令后面加长度:movw %ax,%bx,将16寄存器ax中的内容放到16位寄存器bx中
5、AT&T汇编格式中,绝对转移和调用指令(tmp,call)的 *** 作数前要加上*作为前缀
6、远转移指令和远调用指令的 *** 作码,在AT&T中为ljmp和lcall,Intel中是jmp far,call far
如:AT&T中
Ljmp $section, $offset
Lcall $section,$offset
Intel中
Jmp far section offset
Call far section offset
7、远程返回指令
Lret $stack_adjust(AT&T)
Ret far stack_adjust(intel)
8、寻址方式
Section disp(base,index,scale)表示,计算方法是:base+indexscale+disp (AT&T)
Section [base+indexscale+disp] (intel)
如:AT&T中
Movl -4(%ebx),%eax 将ebx值减4后得到的地址开始的4字节内容放到eax中
Movl array(,%eax,4),%eax 将eax值乘4后得到的地址开始的4字节内容放到eax中
Movw array(%ebx,%eax,4),%cx 将ebx+eax*4得到的地址开始的4字节内容放到cx中
二、AT&T中的c语言中调用嵌入式汇编语句的语法
1、格式
asm(“asm statements”:outputs:inputs:registers-modified)
asm_statements:
1.1、引号内部存放的是汇编语句,一组引号内可以存放多条汇编语句,中间用分号分开。
也可以使用多组引号,非结尾处的会变语句后面要加上\n\t
如:
asm(“pushl %%eax \n\t”
“movl $0,%%eax \n\t”
“popl %%eax”);
1.2、后面的三个是可选项,如果只省略中间的inputs,语法上应该用两个冒号放在中间,例如当有outputs和registers但没有inputs时,语法是output::registers-modified
1.3、注意:此处的引用寄存器的值得时候使用的是%%,因为在c语言中的嵌入式汇编语句,会因先转换成汇编而去掉一个%,为避免到了汇编后引用寄存器缺失%,c语言中的嵌入式语句使用%%引用寄存器
2、参数含义
2.1、Outpus:汇编代码执行完以后将结果输出到指定的寄存器,一般会在寄存器后面接一个变量,用于获取寄存器中的值
2.2、Inputs:汇编代码执行前需要传入的参数,一般会在寄存器后面加一个变量用于将值传给寄存器
2.3、registers-modified:表示在执行这篇汇编代码时会修改的寄存器
如:
{register char _res:
Asm(“push %%fs\n\t”
“movw %%ax,%%fs\n\t”
“pop %%fs”
:”=a(_res)”:”0”(seg):”m”(*(addr))
);
_res;
}
2.4、注意:作为outputs的出参寄存器前面有个=,”0” 表示使用前一个寄存器,此处就是前面的a
3、示例
Int main()
{
Int a1=10,b1=0;
asm(“movl %1,%%eax;\n\r”
“movl %%eax,%%ecx;”
:”=a”(b1)
:”b”(a1)
:”%eax”
);
Prints(“Result:%d,%d\n”,a1,b1);
}
3.1、%0,%1,%2依次对应到outputs,inputs,register-modified
3.2、“a””b””c””d”分别表示寄存器eax,ebx,ecx,edx
3.3、“S””D”表示寄存器esi,edi
3.4、“r”任何寄存器
3.5、“0” 表示前一个寄存器
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)