您的位置:首页 > 运维架构 > Linux

Linux 内核入门学习笔记(一) AT&T汇编基础

2011-02-23 21:00 1056 查看
AT&T汇编语法格式
寄存器引用
引用寄存器要在寄存器号前加% mov % eax, % ebx
操作数顺序
从左到右  mov % eax(源) , % ebx(目的)
常数/立即数的格式
立即数前要加$   mov $4 , % ebx
符号常数直接引用 mov value , % ebx
引用符号地址在符号前加 $  mov $value, % ebx
操作数的长度
操作数的长度用加在指令后的符号表示
b(byte) w(word) l(long)    movw %ax, %bx(表示移动一个16位字从ax移动到bx)
AT&T汇编格式中,绝对转移(jmp)和调用指令(call)操作数前要加上 * 作为前缀
远转移指令和远调用指令的操作码,在AT&T为ljmp 和 lcall 在Intel中为 jmp far
call far
Intel格式
jmp far section:offset 跳转到section段offset偏移的地址处
call far section:offset 调用section段offset地址处函数
AT&T
ljmp $section, $offset
lcall $section, $offset
远程返回指令
lret $stack_adjust (?堆栈的栈阶数)
ret far stack_adjust
寻址方式
Intel
section:[base + index*scale + disp]
section段的base加index(索引)乘以比例因子加位移量
AT&T
section:disp(base,index,scale)

movl -4(%ebp), %eax  Intel  mov eax, [ebp -4]
移动一个long(32位)数从ebp地址中的数减去4放到eax地址中
movl arry(, %eax, 4), %eax  Intel  mov eax, [eax*4 + array]
把array加上eax地址中的long数乘以4放到eax中
movw array(%ebx, %eax, 4), %cx   Intel  mov cx, [ebx + 4*eax + array]
移动一个word(16位) 把array中的数加上ebx 再加上eax地址上的数乘以4 放到16位寄存器cx中
movb $4, %fs:(%eax)   Intel mov fs:eax , 4;
移动一个八位的立即数4放到目的地fs段的偏移位eax的地址
内核中的嵌入汇编
AT&T嵌入汇编格式
_asm_("汇编语句": 汇编代码执行完毕后输出的寄存器 : 在汇编代码执行前需要输入的参数 :  代码执行过程中会被修改的寄存器);
_asm_没有下划线意义相同,"汇编语句"可以放多条,后面三个是可选项
_asm_("pushl %%eax /n/t"	//eax压入堆栈
"movl $0, %%eax /n/t"		//把立即数0放入eax栈中
"popl %eax");				//弹出堆栈中32位数内容到eax
gcc编译c语言源程序的时候要把源程序先转换成汇编格式,会把%%去掉一个,所以要加两个%
{register char _res;/			//定义一个寄存器变量
asm("push %%fs/n/t"			//把fs压入堆栈
"movw %%ax, %%fs/n/t"		//ax中的内容(seg中的值)放到fs中
"mov %%fs:%2,%%al/n/t"		//把fs段中序号为2的输入寄存器中的数(*addr)取出一个字节放到al中
"pop %%fs"					//弹出fs到0号的输出寄存器a(_res)再获取结果
:"=a(_res):"0"(seg),"m"(*(addr))):/			//第一个冒号后输出寄存器es 赋给_res 第二个冒号表示输入寄存器 seg和addr是之前定义的变量int型和字符串型 "0"(seg)表示把变量seg中的内容赋给0(位置为0的输出寄存器),*(addr)代表的地址赋给m(内存地址)
输出寄存器和输入寄存器安装从0到9排序,输出寄存器只有一个0,输入寄存器可以有多个
_res :}    					//返回_res
int main()
{
int a1= 10,b1 = 0;
_asm_("movl %1, %%eax; //n//r" 	//把1号参数中的值ebx中的a1赋给eax
"movl %%eax, %%ecx;"			//把eax中的内容赋给ecx
:"=a"(b1)						//0号参数=a表示输出寄存器eax,把输出的eax的内容赋值给b1
:"b"(a1)						//1号参数把a1中的内容到ebx
:"%eax");						//代码过程中会改变的寄存器eax
printf("Result: %d, %d//n", a1,b1);}
}
打印结果 Result: 10, 10
"a" "b" "c" "d"分别表示寄存器eax, ebx, ecx, edx
"S"和"D"表示寄存器esi,edi,串操作中用到
"r" 表示任何寄存器
"0"表示与上面位置相同的同一寄存器

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  汇编 at&t linux byte 语言 c