美文网首页
linux栈的增长方向

linux栈的增长方向

作者: freelands | 来源:发表于2017-01-07 11:54 被阅读196次

之前我一直以为,栈的增长方向是从低地址到高地址,今天发现linux kernel不是这样的,接下来我们就来看一下吧。

在说之前,需要指出的就是 eax是通用寄存器,esp是和堆栈相关的,栈顶指针寄存器,ebp是栈低指针寄存器。

片段一

pushl %eax

片段一表示的是把寄存器eax里的值,压入栈中。 其实 l 表示的是16位的寄存器和 eax (eax是16位的寄存器 ax是8位的寄存器)所对应。

片段二

subl $4, %esp
movl %eax, (%esp)

片段二中的第一条指令表示的是,首先把esp寄存器,也就是栈顶指针的值,先减去4,然后再把eax寄存器里的值,放入esp所指的地址处。

因此可以看出,push操作,栈顶往低的地址方向移动,所以栈的增长方向就是从高地址往低地址。同理pop操作和push相反。如下:

popl %eax

相当于下面两条指令

movl (%esp), %eax
addl $4, %esp

引申

我们都知道,cpu 做的事就是取指然后执行,这样不断的重复。
那么指令从哪里取呢?就是从cpu里的一个寄存器里,叫做ip,ip保存的是下一条cpu要执行指令的地址,cpu每执行完一条指令,ip就会自动+1。
那么函数调用时怎么实现的呢?

片段三

call 0x12345

这条指令就是执行函数的调用,但是这背后到底做了什么呢?对程序计数器有什么样的影响呢?我们接着往下看。

片段四

pushl %eip
movl $0x12345, %eip

其实片段三的执行函数调用的指令,就相当于片段四的这两条指令。
先把当前的eip指针压栈,然后把执行函数调用的入口地址,传给eip。
可以看出,函数调用打破了,cpu顺序取指,执行。

那么函数调用结束后,会怎么办呢?

片段五

popl %eip

当然是要恢复执行函数调用前的eip,这样cpu才可以接着从函数调用前的那个指令继续执行下去。

在这里还有一点需要注意的是,eip寄存器不能被直接修改,只能通过一些特殊指令间接的修改。

相关文章

  • linux栈的增长方向

    之前我一直以为,栈的增长方向是从低地址到高地址,今天发现linux kernel不是这样的,接下来我们就来看一下吧...

  • 内存堆和内存栈的区别

    内存栈: 内存中的栈区处于相对较高的地址以地址的增长方向为上的话,栈地址是向下增长的。 系统自动申请空间,且自动释...

  • 栈和堆的增长方向

    首先,在C++中,内存分为5个区域,分别是栈、堆、自由存储区、全局/静态存储区和常量存储区。 图片引用http:/...

  • 2. 进程栈和线程栈

    Linux 中的各种栈:进程栈 线程栈 内核栈 中断栈 - 木易博客专栏 - CSDN博客 栈的作用:函数调用和多...

  • Linux 命令栈

    Linux 命令栈 转至:http://www.runoob.com/linux/linux-command-ma...

  • __stack_chk_fail 崩溃问题

    参考:栈检查失败Linux 栈溢出 __stack_chk_fail 是指栈检查失败,具体是的 sp 指针与保存的...

  • 用户态协议栈的实现

    协议栈,指的是TCP/IP协议栈。linux系统中,协议栈是内核实现的。 Client发送数据给server,数据...

  • CPU上下文切换

    栈空间 用户态函数栈主要用于用户态的函数调用image.png 内核栈Linux 给每个 task 都分配了内核栈...

  • Go 语言设计与实现-Part2

    20.栈内存管理 linux内存布局下图是 Linux 下一个进程里典型的内存布局image.png 栈是由高地址...

  • 10章 内存: 进程地址空间 / 函数调用栈 & 反汇编 / h

    1 Linux 进程地址空间 布局 2 栈 与 调用惯例 (1) 栈 & 函数调用 机制 进入 funcBody ...

网友评论

      本文标题:linux栈的增长方向

      本文链接:https://www.haomeiwen.com/subject/lohfbttx.html