作者:申小宁 原创作品转载请注明出处
《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 

实验截图:


c代码:


wKioL1T8V1CxnVmrAADs1Jxm3X0686.jpg


编译命令:

wKiom1T8VmOCxTscAABYXJAWEn0319.jpg


汇编代码:

wKioL1T8V1HBloEiAAKoslH1NIo055.jpg


基础知识


寄存器

寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令,数据和地址。

eip:存储当前指令寄存器,每执行完一条指令,eip将指向下一条指令。

ebp:是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:

esp:专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,ESP也就越来越小。在32位平台上,ESP每次减少4字节。

eax:是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。


寻址方式

寄存器寻址  movl %eax,%ebx   把eax的值,赋给ebx

立即寻址 movl $0x1234,%eax   把0x1234这个立即数,赋值给eax。

直接寻址 movl 0x12345,%eax   把0x12345这个内存地址存放的数据赋值给eax。

间接寻址 movl (%eax),%ebx    eax上存放的一个内存地址,这个内存地址存放的值,赋值给ebx。

变址寻址 movl 8(%eax),%ebx    eax上存放的值,加上偏移量8 后,所指向的位置存放的内存地址,这个内存地址存放的值,赋值给ebx


从main函数入手:

第一句:pushl %ebp

Pushl  %ebp(表示把eax寄存器的内容压倒栈顶):

等价于:

subl  $4,%esp (堆栈的栈顶)   

movl  %ebp,(%esp)

 第二句:movl %esp, %ebp

使得ebp指向esp指向的位置。

第三句:subl $4, %esp

栈顶向下偏移4个字节。

第四句:movl $99, (%esp)

将一个立即99存入栈顶。

第五句:call f 即调用函数f()

call 指令可分解成 

pushl eip

movl f eip


f函数

pushl %ebp (存储EBP位置,压栈,esp加一)

movl %esp %ebp (esp 指向EBP)

...

movl %eax (%esp)

把esp存储内存地址 指向 eax寄存器

call g执行函数g


g函数


ret  函数返回作用 返回执行gax内的指令。


总结:汇编语言是计算机语言的基础,想要深入理解linux内核或者学习一些其他语言,汇编都是基础,小伙伴们加油了!!!