函数的X86-64实现

  • 工具:指令+约定+存储(寄存器和栈内存)
  • 怎么实现?

基本问题

  • 什么时候需要栈?什么时候不需要栈?

怎么实现?

  • 只使用寄存器
    当只有一个函数P时,且函数P没有调用任何函数,且函数P的参数不超过6个,且函数P的所有局部变量都可以保存在寄存器中;
  • 使用寄存器加栈;
    必须要使用栈,可以方便地函数Q执行返回后,继续执行函数P;

函数调用

假设函数P调用函数Q,然后函数Q执行,返回给函数P,这三个操作涉及以下3种机制:

  • 控制权转移
    调用函数Q时,将程序计数器设置为函数Q代码的开始地址;
    调用结束返回时,将程序计数器设置为调用函数Q指令的下一个指令;
  • 数据传递
    函数P必须提供函数Q执行所需的多个参数;
    函数Q必须能传递一个返回值给函数P;
  • 内存分配和释放
    当函数Q开始执行时,函数Q可能需要分配内存用于存储局部变量;
    当函数Q执行结束返回给函数P时,需要释放之前分配的内存;

函数的X86-64实现
特殊指令+特殊约定

当函数Q在执行时,函数P被临时挂起;
当函数Q在执行时,只有函数Q需要分配新的内存来用于存储局部变量或者建立对另一个函数的调用;
当函数Q返回时,其创建的任何局部内存都会被释放;

X86-64的栈是从高地址向低地址增长的;
%rsp指向的是栈顶元素;
使用pushqpopq指令来往栈上存储数据和从栈上获取数据;
没有具体初始值的数据,即临时变量所需的内存空间分配是通过将栈指针递减某个合适的量来的;
类似的,这部分空间的释放是将栈指针递增某个合适的量实现的;

什么时候需要在函数栈?
当X86-64的函数需要的内存超过寄存器的内存时,就需要在函数栈上分配内存了;

一个函数在栈上分配的内存区域,叫做函数的栈帧;

运行时栈run-time stack

大部分函数的栈帧都是大小固定的;
有些函数的帧需要大小可变;

当前正在执行的函数的帧通常位于栈顶;

当函数P调用函数Q时,要将函数Q的返回地址压入函数P的栈帧中;

函数Q的栈帧分配及构成

  • 通过拓展当前栈边界来分配函数Q所需的空间;
  • 如何利用这份空间,即函数Q的栈帧?
    保存寄存器的值;
    分配局部变量的存储空间;
    设置函数Q需要调用的其他函数的参数;

函数Q栈帧的构成

  • 寄存器的值;
  • 局部变量的值;
  • 函数Q需要调用的其他函数的参数值;

函数P总共可以传递给6个整数值,包括指针值和整数,这些值保存在6个寄存器中(%rdi, %rsi, rdx, %rcx, %r8, %r9);
如果函数Q需的参数值超过6个,则在调用函数Q之前,将这些参数值保存在函数P的栈帧中;

X86-64按需分配函数的栈帧;
加速大概率事件
比如,大部分函数的参数都不超过6个,这些参数值都是通过寄存器来传递的;
当一个函数的所有局部变量都可以使用寄存器保存,且不调用任何函数时,就不需要给这个函数在栈上分配帧,即这个函数的栈帧就不存在;

运行时栈

不是所有的函数都有栈帧;

控制权转移

  • 函数P将控制权转移给函数Q
    设置程序计数器的值为函数Q的代码的开始地址;
  • 函数Q将控制权转移给函数P
    必须要记录函数P调用函数Q完成后要执行的代码位置;
    什么时候发生?
    指令call Q发生时;
    怎么记录?
    指令call Q将返回地址A压入函数P的栈中;
    怎么清除?
    指令ret将返回值A从函数P的栈帧中弹出;

函数调用指令

  • call Q
    将返回地址A压入函数P的栈中,设置PC为函数Q的开始地址;
    返回地址A的值为函数P中调用函数Q后的下一个指令的地址;
    call指令的跳转分为两类,一个是直接跳转;另一类是间接跳转;
    call指令的操作数指示着函数Q的开始的地址,即函数Q的开始地址;
  • ret
    从函数P的栈帧中弹出返回地址A,设置PC的值为返回地址A;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容