课程主页:https://courses.cs.washington.edu/courses/cse351/16sp/

课程资料:

实验部分:https://github.com/vuquangtrong/HW-SW_Interface_Course

实验说明:https://courses.cs.washington.edu/courses/cse351/13sp/lab-0.html

课件:http://academictorrents.com/details/b63a566df824b39740eb9754e4fe4c0140306f4b

课程视频:https://www.bilibili.com/video/BV1Zt411s7Gg?from=search&seid=8781593976070799647

这次回顾第五部分,这部分介绍了进程和堆栈。

第5节:进程和堆栈

这部分和课件略有不同,主要介绍x64体系结构。

内存中的堆栈和堆栈操作

内存布局

x86-64栈
  • 通过栈规范管理内存区域
  • 栈顶在低地址
  • 寄存器%rsp为最小的堆栈地址
    • 即“顶部”元素的地址

Push
  • pushq Src
  • 将%rsp减少8
  • 在给定的地址%rsp处写入操作数

Pop
  • popq Dest
  • 在%rsp指定的地址处读取值
  • 将%rsp增加8
  • 将值存储在Dest

备注:课件中介绍的是IA32,所以要将8改成4。

用于跟踪过程调用的堆栈

过程调用概况

  • Callee必须知道在哪里可以找到参数
  • Callee必须知道在哪里可以找到“返回地址”
  • Caller必须知道在哪里可以找到返回值
  • Caller和Callee在同一CPU上运行→使用相同的寄存器
    • Caller可能需要保存Callee可能使用的寄存器
    • Callee可能需要保存Caller已经使用的寄存器

  • 离开/发现事物的惯例称为过程调用链接
    • 详细信息因系统而异
    • 我们将详细了解IA32/Linux的约定
    • 如果我们的程序没有遵循这些惯例,会发生什么情况呢?
过程控制流
  • 使用栈来支持过程调用和返回
  • 程序调用:call label
    • 将返回地址推入堆栈
    • 跳转到label
  • 返回地址:

    • call之后下一条指令的地址

    • 例子

      804854e:	e8 3d 06 00 00 	call   8048b90 <main>
      8048553:	50             	pushl  %eax
    • 返回地址=$0\text{x}8048553$

  • 程序返回:ret
    • 从栈中弹出地址
    • 跳转到地址

基于堆栈的语言

栈帧
  • 内容
    • 返回信息
    • 本地存储(如果需要)
    • 临时空间(如果需要)
  • 管理
    • 进入过程时分配空间
      • “Set-up”代码
      • 包括call指令
    • 返回时取消分配
      • “Finish”代码
      • 包括ret指令

#####

Linux堆栈框架

x86-64/Linux栈帧
  • 当前栈帧(“顶部”至底部)
    • Argument build:要调用的函数的参数
    • Local Variables(如果没法存储在寄存器中)
    • Saved Registers(如果复用寄存器)
    • Old frame pointer(可选)
  • Caller栈帧
    • Return address
      • 由call指令push
    • 此次call的参数

寄存器保存约定

  • 当过程yoo call who:
    • yoo是caller
    • who是callee
  • 可以将寄存器用于临时存储吗?
  • 约定
    • “Caller Saved”
      • caller在call之前将临时值保存在其帧中
    • “Callee Saved”
      • callee在使用前将临时值保存在其帧中
      • callee在返回到caller前将这些值恢复
x86-64/Linux寄存器用处
  • %rax
    • 返回值
    • 也是caller-saved
    • 可以通过过程修改
  • %rdi,…,%r9
    • 参数
    • caller-saved
    • 可以通过过程修改
  • %r10,%r11
    • caller-saved
    • 可以通过过程修改
  • %rbx,%r12,%r13,%r14
    • callee-saved
    • callee必须保存并还原
  • %rbp
    • callee-saved
    • callee必须保存并还原
    • 可用作帧指针
    • 可以混合搭配
  • %rsp
    • 特殊形式的callee-saved
    • 退出程序后恢复到原始值