一、实验记录

1、实验代码截屏

实验记录

本次实验中遇到的一个小问题是:
(1)在进行汇编语言编译时,命令行本应是"g/.s*/d ",因为做实验的时候还没有看视频,只是看了书,把"/ "当成了“^",在这里,需要用转义字符。
(2)其中,:g/pattern/d表示全局删除匹配到的行。


二、《庖丁解牛Linux内核分析》第一章学习

(一)注意

1、堆栈是向下增长的,地址在减小,需要与栈进行区分。
2、SP栈顶指针寄存器,BP栈底指针寄存器。SP总是指向栈顶,BP指向的是当前函数堆栈的栈底。


(二)call指令的学习(以32位为例):

在刚开始看到课本的第10页call指令的两条伪指令时,以为应该把改变后的EIP中的值压栈,直到看完整章内容,才知道call指令的含义。
两条伪指令为(实际上,IP不可通过pushl以及movl指令所修改):

pushl %eip
movl $0×12345,%eip

call指令的含义是:先将调用函数前应该执行的指令地址压栈,等所调用函数执行完毕,便于回到main函数;然后将被调用函数的第一条指令地址放入EIP。


(三)enter指令的学习(以32位为例)

enter指令用于建立函数堆栈,等价于:

pushl %ebp
movl %esp,%ebp

首先将栈底指针寄存器压栈,记录本函数的栈底。然后重新将EBP赋值为新进入函数的栈底。


(四)leave指令的学习(以32位为例)

leave指令用于撤销函数堆栈,等价于:

movl %ebp,%esp
popl %ebp

撤销函数堆栈,将ESP赋值为EBP,然后将EBP出栈。
经过查看实验中的汇编代码,g函数中没有使用leave,而f函数中使用了leave指令,那么,什么时候要用leave,什么时候用ret?
汇编文件:

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
    leave
    ret 
main:
    pushl %ebp
    movl %esp,%ebp
    subl $4, %esp
    movl $8,(%esp)
    call f
    addl $1,%eax
    leave
    ret

查阅资料发现:

二者的差别就在于是否使用 movl %ebp, %esp。
这句的作用是用来恢复堆栈的栈顶指针,堆栈的栈顶指针没有变化的时候,就可以不用恢复,直接使用popl指令了。

posted on 2019-09-22 15:47  20199302  阅读(201)  评论(1编辑  收藏  举报