main.c

int enable=;

int main()
{
int a, b;
int sum; a = ;
b = ; sum = add(a, b); return ;
} int add(int a, int b)
{
int x, y;
x = a;
y = b;
return (x+y);
} int del()
{
return ;
}

汇编如下:

main.elf:     file format elf32-sparc

Disassembly of section .text:

 <main>:
: 9d e3 bf save %sp, -, %sp
: mov , %o0
: d0 bf f4 st %o0, [ %fp + - ]
7000000c: mov , %o0
: d0 bf f0 st %o0, [ %fp + - ]
: d0 bf f4 ld [ %fp + - ], %o0
: d2 bf f0 ld [ %fp + - ], %o1
7000001c: call 7000003c <add>
: nop
: d0 bf ec st %o0, [ %fp + - ]
: clr %o0
7000002c: b0 mov %o0, %i0
: nop
: c7 e0 ret
: e8 restore 7000003c <add>:
7000003c: 9d e3 bf save %sp, -, %sp
: f0 a0 st %i0, [ %fp + 0x44 ]
: f2 a0 st %i1, [ %fp + 0x48 ]
: f0 a0 ld [ %fp + 0x44 ], %i0
7000004c: f0 bf f4 st %i0, [ %fp + - ]
: f0 a0 ld [ %fp + 0x48 ], %i0
: f0 bf f0 st %i0, [ %fp + - ]
: f2 bf f4 ld [ %fp + - ], %i1
7000005c: f0 bf f0 ld [ %fp + - ], %i0
: b0 add %i1, %i0, %i0
: nop
: c7 e0 ret
7000006c: e8 restore <del>:
: 9d e3 bf save %sp, -, %sp
: b0 clr %i0
: nop
7000007c: c7 e0 ret
: e8 restore
Disassembly of section .data: <enable>:
: unimp 0x1

混合源程序的反汇编如下:局部变量的定义不会增加程序指令。

main.elf:     file format elf32-sparc

Disassembly of section .text:

 <main>:
int enable=; int main()
{
: 9d e3 bf save %sp, -, %sp
int a, b;
int sum; a = ;
: mov , %o0
: d0 bf f4 st %o0, [ %fp + - ]
b = ;
7000000c: mov , %o0
: d0 bf f0 st %o0, [ %fp + - ] sum = add(a, b);
: d0 bf f4 ld [ %fp + - ], %o0
: d2 bf f0 ld [ %fp + - ], %o1
7000001c: call 7000003c <add>
: nop
: d0 bf ec st %o0, [ %fp + - ] return ;
: clr %o0
}
7000002c: b0 mov %o0, %i0
: nop
: c7 e0 ret
: e8 restore 7000003c <add>: int add(int a, int b)
{
7000003c: 9d e3 bf save %sp, -, %sp
: f0 a0 st %i0, [ %fp + 0x44 ]
: f2 a0 st %i1, [ %fp + 0x48 ]
int x, y;
x = a;
: f0 a0 ld [ %fp + 0x44 ], %i0
7000004c: f0 bf f4 st %i0, [ %fp + - ]
y = b;
: f0 a0 ld [ %fp + 0x48 ], %i0
: f0 bf f0 st %i0, [ %fp + - ]
return (x+y);
: f2 bf f4 ld [ %fp + - ], %i1
7000005c: f0 bf f0 ld [ %fp + - ], %i0
: b0 add %i1, %i0, %i0
}
: nop
: c7 e0 ret
7000006c: e8 restore <del>: int del()
{
: 9d e3 bf save %sp, -, %sp
return ;
: b0 clr %i0
}
: nop
7000007c: c7 e0 ret
: e8 restore

1、3个局部变量,共12字节,按照8字节对齐,需要16字节,即104+16=120

: 9d e3 bf  save  %sp, -, %sp

2、main.c将局部变量a,b分配在%fp + -12,%fp + -16

:            mov  , %o0
: d0 bf f4 st %o0, [ %fp + - ]
7000000c: mov , %o0
: d0 bf f0 st %o0, [ %fp + - ]

3、将输入参数放在o0和o1中,然后调用add

:    d0  bf f4     ld  [ %fp + - ], %o0
: d2 bf f0 ld [ %fp + - ], %o1
7000001c: call 7000003c <add>

4、将局部变量sum,放在%fp + -20,调用结束,从o0取得add的返回值。

:    d0  bf ec     st  %o0, [ %fp + - ]

5、add现将i0和i1放在%fp + 0x44,%fp + 0x48,这是为什么?0x44=68, 0x48=72

:    f0  a0      st  %i0, [ %fp + 0x44 ]
: f2 a0 st %i1, [ %fp + 0x48 ]

6、然后,赋值局部变量

:    f0  a0      ld  [ %fp + 0x44 ], %i0
7000004c: f0 bf f4 st %i0, [ %fp + - ]
: f0 a0 ld [ %fp + 0x48 ], %i0
: f0 bf f0 st %i0, [ %fp + - ]

add函数里的%fp + 0x44感觉又到了main的堆栈里了,这是怎么回事?见下面分析。

The caller’s stack pointer %sp (%o6) automatically becomes the current procedure’s frame pointer %fp (%i6) when the SAVE instruction is executed.

SAVE同时也具有ADD的效果。

3803手册中,%fp + 0x44位置处写着,用于存储被调函数的寄存器变量,也就是add函数。在调用函数的堆栈中,为什么要存储被调函数的东西呢?见下面分析

System V Application Binary Interface - SPARC Processor Supplement -3dt,p24描述如下:

Although the first 6 words of arguments reside in registers, the standard stack frame reserves space
for them. ‘‘Coding Examples’’ below explains how these words may be used to implement variable
argument lists. Arguments beyond the sixth reside on the stack.

虽然前6个参数放在寄存器中,但是标准的栈帧也给它们预留了空间。

下面图来自abi_sparc,p24。

其中previous帧中说six words into which function may write incoming arguments 0 to 5,这是里may可能,调用函数可能将前6个输入参数既放入i0~i5,又放在这里。

current帧中说six words into which callee may write outgoing arguments 0 to 5,这是里may可能,被调函数可能将前6个输出参数既放入i0~i5,又放在这里。

但从实际sparc-elf-gcc的使用来看,被调函数做了调用函数的工作,即被调函数将输入参数i0~i5放在了调用函数栈帧的该位置处。

reference:

SYSTEM V APPLICATION BINARY INTERFACE, SPARC Processor Supplement, Third Edition

链接:https://pan.baidu.com/s/1lRCz7Z0nol-8gOzed3Rmyw
提取码:0kjr

BM3803MGRH用户手册

链接:https://pan.baidu.com/s/1T3sNflIAdCUGGcON3-tWpQ
提取码:xkty
复制这段内容后打开百度网盘手机App,操作更方便哦

sparc v8 stack frame calling convention的更多相关文章

  1. Sparc V8

    Sparc V8指令 在sparc V8手册中p83(Table A-1 Mapping of Synthetic Instructions to SPARC Instructions)有合成指令sy ...

  2. X86调用约定 calling convention

    http://zh.wikipedia.org/wiki/X86%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A 这里描述了在x86芯片架构上的调用约定(calling con ...

  3. Calling Convention的总结

    因为经常需要和不同的Calling Convention打交道,前段时间整理了一下它们之间的区别,如下: 清理堆栈 参数压栈顺序 命名规则 (MSVC++) 备注 Cdecl 调用者 (Caller) ...

  4. function calling convention

    这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=31 February 19, 2013 function calling c ...

  5. Stack frame

    http://en.citizendium.org/wiki/Stack_frame In computer science, a stack frame is a memory management ...

  6. How a stack frame works 栈帧的要素与构建步骤

    http://en.citizendium.org/wiki/Stack_frame To use a stack frame, a thread keeps two pointers, often ...

  7. FUNCTION CALL STACK FRAME

    function call stack frame 两个寄存器 esp 栈顶指针寄存器,指向调用栈的栈顶(始终指向,意味着栈分配到哪里了,从当前栈往高地址是已经分配了的) ebp 基址指针寄存器,指向 ...

  8. 从栈不平衡问题 理解 calling convention

    最近在开发的过程中遇到了几个很诡异的问题,造成了栈不平衡从而导致程序崩溃. 经过几经排查发现是和调用规约(calling convention)相关的问题,特此分享出来. 首先,讲一下什么是调用规约. ...

  9. x86-64栈帧中的“红色区域” red zone of stack frame on x86-64

    前几天看System V AMD64 ABI标准的时候发现栈帧的顶部后面有一块"red zone",在学cs:app3e/深入理解操作系统的时候并没有遇到这个,总结一下. 引用标准 ...

随机推荐

  1. CSS中使用文本阴影与元素阴影

    文本阴影介绍 在CSS中使用text-shadow属性设置文本阴影,该属性一共有4个属性值如:水平阴影.垂直阴影.(清晰度或模糊距离).阴影颜色. text-shadow属性值说明,在文本阴影实践中: ...

  2. 如何选择kmeans中的k值——肘部法则–Elbow Method和轮廓系数–Silhouette Coefficient

    肘部法则–Elbow Method 我们知道k-means是以最小化样本与质点平方误差作为目标函数,将每个簇的质点与簇内样本点的平方距离误差和称为畸变程度(distortions),那么,对于一个簇, ...

  3. Mysql.linux登录数据库

    //mysql -hlocalhost -uroot -p //-h数据库地址 -u用户名 -p密码 -P端口号(P大写)//-p可省略,会提示输入密码. mysql -h127. -uroot -p ...

  4. java 方法定义 调用

    一.定义 格式: 修饰符 返回值类型 方法名(参数){ return } 相比之下python方法的定义简单多了 public static 是修饰符 二.调用 方法名(); 注意:要在main方法中 ...

  5. 机器学习-向量机SVM

    一.介绍 二.编程 1.支持向量机的核函数 import numpy as npimport matplotlib.pyplot as pltfrom sklearn import svmfrom s ...

  6. pywin32 获取 windows 的窗体内文本框的内容

    用 spy++去确认找到了文本框的句柄了. 用函数 win32gui.SendMessage 获取不了文本框的文本内容,用 str 类型的参数接收获取的内容的话没有获取到东西,而用 PyBuffer ...

  7. 每天玩转3分钟 MyBatis-Plus - 6. select 用法

    每天玩转3分钟 MyBatis-Plus - 1. 配置环境 每天玩转3分钟 MyBatis-Plus - 2. 普通查询 每天玩转3分钟 MyBatis-Plus - 3. 高级查询(一) 每天玩转 ...

  8. NVIDIA DRIVE

      NVIDIA 驱动安装(超详细) ref1: https://blog.csdn.net/qlulibin/article/details/78714596 ref2:https://www.cn ...

  9. 机器学习李航——Adaboost课本例题实现

    例8.1Adaboost的例子 注意求D3或者D4的时候只需要把w替换一下就行,记得还得改阈值.这个代码算个半自动的,因为还需要手动改一下. import numpy as np def getA(e ...

  10. Nutz框架-- Cnd条件使用原生sql

    案例 今天接到一个临时的业务需求,做一个简单的过滤作为临时业务需要使用一两天,于是想到在原有的Cnd条件上加上一个Not like 进行过滤,但是发现现有Cnd条件查询好像满足不了 解决方案 使用Nu ...