X86汇编基础-《Linux内核分析》云课堂笔记
X86CPU的寄存器
EAX 累加器(Accumulator)
EBX 基地址寄存器(Base Register)
ECX 计数寄存器(Count Register)
EDX 数据寄存器(Data Register)
EBP 堆栈基指针(Base Pointer)
ESI EDI 变址寄存器(Index Register)
ESP 堆栈顶指针(Stack Pointer)
CS——代码段寄存器(Code Segment Register),其值为代码段的段值;
DS——数据段寄存器(Data Segment Register),其值为数据段的段值;
ES——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
SS——堆栈段寄存器(Stack Segment Register),其值为堆栈段的段值;
FS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值;
GS——附加段寄存器(Extra Segment Register),其值为附加数据段的段值。
内存指令
Memory instructions: MOV, PUSH, POP, etc
• Most instructions can take a memory address
• b,w,l,q分别代表8位,16位,32位和64位
movl %eax, %edx edx = eax; register mode
movl $0x123, %edx edx = 0x123; immediate
movl 0x123, %edxedx = (int32_t)0x123; direct
movl (%ebx), %edx edx = (int32_t)ebx; indirect
movl 4(%ebx), %edx edx = (int32_t)(ebx+4); displaced
pushl %eax
subl $4, %esp
movl %eax, (%esp)
popl %eax
movl (%esp), %eax
addl $4, %esp
call 0x12345
pushl %eip()
movl $0x12345, %eip()
ret
popl %eip(*)
enter
pushl %ebp
movl %esp, %ebp
leave
%ebp, %esp
popl %ebp
(堆栈向下增长的,向下地址越小)
练习
pushl$8
movl %esp, %ebp
subl $4, %esp
movl $8, (%esp)
pushl$8
movl %esp, %ebp
pushl$8
pushl$8
movl %esp, %ebp
pushl%esp
pushl$8
addl $4, %esp
popl %esp
反汇编一个简单的C程序
把C代码编译成汇编代码命令: gcc -S -o main.s main.c -m32
汇编代码中以.开头的内容是用于链接时的辅助信息,不在实际中执行
eip 指向要执行的指令
ebp 指向堆栈的栈底(相对) (函数调用堆栈是由逻辑上多个堆栈叠加起来的)
esp 指向堆栈的栈顶 (相对)
eax 用于暂存一些数值 (函数的返回值默认使用eax寄存器存储返回给上一级函数)
C代码:
int g(int x)
{
return x+3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8)+1;
}
汇编代码:
...
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $3, %eax
popl %ebp
ret
...
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
movl %ebp,%esp
popl %ebp
ret
...
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $8, (%esp)
call f
addl $1, %eax
movl %ebp,%esp
popl %ebp
ret
...
练习:写出对应的C代码
...
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $8, %eax
popl %ebp
ret
...
main:
pushl %ebp
movl %esp, %ebp
pushl $8
call g
subl $8, %eax
movl %ebp,%esp
popl %ebp
ret
...
答案:
int g(int x)
{
return x + 8;
}
int main(void)
{
return g(8) - 8;
}