ARM汇编之栈

创建进程的时候,会分配内存作为栈。
实际栈指令(push,pop)是其他指令的别名,实际指令是STR、LDR或者其延伸指令。例STMDB sp,{R0,R1}== push {r0, r1}

栈实现的几种情况
堆栈类型 store load
完全下降(高地址在上,低地址在下) STMFD(STMDB) LDMFD(LDM)
完全升序(高地址在下,低地址在上) STMFA (STMIB) LDMFA (LDMDA)
空升序(高地址在下,低地址在上) STMEA (STM) LDMEA (LDMDB)
空降序(高地址在上,低地址在下) STMED (STMDA) LDMED (LDMIB)

总结:

  • 升序A:高地址在下,低地址在上
  • 降序D:高地址在上,低地址在下
  • 完全F:入栈的时候:SP先减4,然后在写数据。出栈的时候:先写数据再执行SP+4
  • 空E:入栈的时候:先写数据,然后再SP减4。出栈的时候:先执行SP+4再写数据

基础姿势:栈操作

返回地址LR:当前函数执行完,跳转的下一条指令,通常是call当前函数所在地址的下一条地址。例如,下面的代码中:当执行进son_add函数中时,返回地址就是int c=10;这条指令的地址,确保执行完son_add函数后,返回到父函数father中继续执行流程,调用后面的代码。也就是数返回地址保证的是每一个函数块间的指令流程

PC:程序计数器,通常指向下一条指令的地址。例如:当前程序执行到了int a=8;,当处理器编译这条指令的时候,PC所存储的值,就是int b = 9;这条指令的内存地址,也就是PC寄存器保证的是每一条指令间的指令流程

栈帧(r11):函数调用的时候,会在栈中进行,每一个函数执行过程就是一个栈帧

帧指针: 栈帧首地址的内存地址。也就是返回地址的内存地址

int son_add(int a, int b)
{
        return a+b;
}
int father()
{
        int a = 8;
        int b = 9;
        int sum = 0;
        sum = son_add(a, b);
        int c=10;
        return sum;
}

栈帧结构:下面这个图可以适用于上面代码中的fahter函数,如果是son_add的栈帧,只需要减少一步:返回地址的入栈操作,为什么会少这一步呢?首先需要知道:lr只表示当前函数的返回地址,如果当前函数有子函数,进入子函数lr就需要保存子函数的返回地址,但是父函数的返回地址就会被覆盖,所以需要先存起来,等子函数执行完成返回到父函数执行流程中,重新将返回地址存入lr中即可。因为上面的子函数内部不需要调用函数,所以不存在覆盖情况,就只用lr即可。

函数栈调用的详细分析

  • 当函数传入的参数超过4个时,需要用到堆栈存储其余参数
  • r0来保存返回结果
  • 当返回结果超过32位,就需要用r0和r1结合来保存结果
/* azeria@labs:~$ gcc func.c -o func && gdb func */
int main()
{
 int res = 0;
 int a = 1;
 int b = 2;
 res = max(a, b);
 return res;
}

int max(int a,int b)
{
 do_nothing();
 if(a<b)
 {
 return b;
 }
 else
 {
 return a;
 }
}
int do_nothing()
{
 return 0;
}
序幕:为函数设置环境、
push   {r11, lr}    /* 序幕开始:保存帧指针和返回地址到堆栈*/
add    r11, sp, #0  /* 设置当前栈帧的帧指针,指向栈帧的头部地址,即返回地址的地址 */
sub    sp, sp, #16  /* 序幕结束:会根据参数和局部变量分配相应的堆栈空间 */
函数的正文:实现函数的逻辑,并将返回结果赋值给r0
mov    r0, #1       /*传入参数 */
mov    r1, #2       /*传入参数 */
bl     max     
结尾:恢复到初始状态,以便从父函数离开的地方继续执行
sub    sp, r11, #0  /* 调整栈指针 */
pop    {r11, pc} /* 恢复帧指针,并将返回地址放入pc中,实现直接跳转到返回地址处。在此步骤中,栈帧会被销毁 */
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容