💻 CSC3060 Week 5 Continuation of Machine Level Programming
其它学生:学者引用文献需要遵守 APA/MPA/Chicago 等引用格式,否则会爽吃 Fail。
SDS 学生:计算机调用需要根据 Calling Convention,不然你们写论文的计算机爽吃 UB 原地升天,你们签名承诺不用但还是偷偷用的互联网大模型爽吃 504 Error。
Week 5 Calling convention and Its Registers
Calling Convention 包括:参数、返回值/地址、传参、出入栈、fp 的建立和还原、调用方/被调用方保存的寄存器。
调用的约定
在机器的宏观视角下,函数/过程调用的流水线:
从调用方 (Caller) 开始…
- 准备参数(寄存器不够/需要按约定放栈时就放栈上)
- 保存返回地址(ret)
- 跳转到被调函数
工作移交到被调用方 (Callee)…
-
建立栈帧 (Stack frame):栈指针下移,给调用方的栈帧/局部变量/保存寄存器留空间(sp -= stackFrame)
-
保存需要保存的寄存器
-
执行函数主体
-
准备返回值(可能放寄存器 a0/a1,也可能放栈)
-
**恢复保存的寄存器 **并 返回调用方位置
- ⚠️ “栈帧” 是栈上分配给函数的私有区域,每个函数有自己独立的一段帧 (向下分配);“帧指针 fp” 是函数栈帧的寻址基点,这里用于返回后将栈变回调用前的原样。
Meanwhile,栈身上发生了什么?
- 第 1~3 步 (处于调用方) 时,调用者建立自己的栈帧将参数 (如果 a0~a7 放满了) 和返回地址入栈;
- 第 4~7 步 (处于被调用方) 时,被调用者建立新栈帧,将局部变量、要保存的寄存器 (saved regs)、动态对象入栈到这个帧中;
- 第 8 步 (回到调用方) 后,被调用者的栈帧被出栈,栈回到第 1 步之前的样子,fp/sp 指向原先位置。
“Saved Regs”
ABI 规定了一些需要分工在栈中保存下来的寄存器。防止连环调用时关系混乱导致变量覆盖或生命周期错误。逻辑上类似于——
“单位的电脑属于信息部 (Caller),但所有电脑都有信息/公关两部门的账号。公关部 (Callee) 帮信息部的忙,借用电脑后要负责把账号切回信息部 (Callee-saved);而信息部负责留档自己电脑上的重要文件 (Caller-saved)。”
A) Callee-saved (被调用者必须保存)
- s0–s11 (saved regs)、 (old) fp —— 常用 s0 (即 x8) 充当 fp、CSEs。
规则:B 如果要用/改这些寄存器,必须先保存旧值,返回前恢复。
→ 这些被调用者存到栈里的备份,就属于 saved regs,一般生命周期较长。
B) Caller-saved (调用者必须保存)
- t0–t6 (临时变量)、a0–a7 (参数)、ra (返回地址)。
规则:B 可以随便改。A 如果在 call 之后还要用,就必须自己先存起来。
→ 一般生命周期较短。
还学啥,过年去了