sparc v8 stack frame calling convention
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
链接:https://pan.baidu.com/s/1T3sNflIAdCUGGcON3-tWpQ
提取码:xkty
复制这段内容后打开百度网盘手机App,操作更方便哦
sparc v8 stack frame calling convention的更多相关文章
- Sparc V8
Sparc V8指令 在sparc V8手册中p83(Table A-1 Mapping of Synthetic Instructions to SPARC Instructions)有合成指令sy ...
- X86调用约定 calling convention
http://zh.wikipedia.org/wiki/X86%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A 这里描述了在x86芯片架构上的调用约定(calling con ...
- Calling Convention的总结
因为经常需要和不同的Calling Convention打交道,前段时间整理了一下它们之间的区别,如下: 清理堆栈 参数压栈顺序 命名规则 (MSVC++) 备注 Cdecl 调用者 (Caller) ...
- function calling convention
这是2013年写的一篇旧文,放在gegahost.net上面 http://raison.gegahost.net/?p=31 February 19, 2013 function calling c ...
- Stack frame
http://en.citizendium.org/wiki/Stack_frame In computer science, a stack frame is a memory management ...
- How a stack frame works 栈帧的要素与构建步骤
http://en.citizendium.org/wiki/Stack_frame To use a stack frame, a thread keeps two pointers, often ...
- FUNCTION CALL STACK FRAME
function call stack frame 两个寄存器 esp 栈顶指针寄存器,指向调用栈的栈顶(始终指向,意味着栈分配到哪里了,从当前栈往高地址是已经分配了的) ebp 基址指针寄存器,指向 ...
- 从栈不平衡问题 理解 calling convention
最近在开发的过程中遇到了几个很诡异的问题,造成了栈不平衡从而导致程序崩溃. 经过几经排查发现是和调用规约(calling convention)相关的问题,特此分享出来. 首先,讲一下什么是调用规约. ...
- x86-64栈帧中的“红色区域” red zone of stack frame on x86-64
前几天看System V AMD64 ABI标准的时候发现栈帧的顶部后面有一块"red zone",在学cs:app3e/深入理解操作系统的时候并没有遇到这个,总结一下. 引用标准 ...
随机推荐
- 哪些工具可以提升PHP开发效率
本文就我自己在开发过程中的一点经验,谈谈如何利用工具来提升开发工作的编码效率, IDE(phpstorm 收费) 一个好的IDE真的可以给开发人员节省大量的时间,我从最开始使用editplus 到su ...
- 微信小程序----日期时间选择器(自定义精确到分秒或时段)
声明 bug:由于此篇博客是在bindcolumnchange事件中做的值的改变处理,因此会出现当你选择时,没有点击确定,直接取消返回后,会发现选择框的值依然改变.造成原因:这一点就是由于在bindc ...
- FWT 入门
#include <bits/stdc++.h> using namespace std; #define ll long long const ll maxn = 3e5+5; cons ...
- 如何配置好Selenium2Library的环境
1.首先是下载如下文件 1,ActivePython-其自带了pip工具,很方便,记得选择activepython是2.7x版本的python: 2.依次安装wxpython,Robotframewo ...
- Java入门 - 面向对象 - 01.继承
原文地址:http://www.work100.net/training/java-inheritance.html 更多教程:光束云 - 免费课程 继承 序号 文内章节 视频 1 概述 2 继承的特 ...
- 把 CPU “玩”起来
前言 从开始学习编程之后,就渐渐痴迷于技术,平时遇到购书满减活动时就忍不住买一堆书.前两天闲着无聊,翻开了去年买的<编程之美>,目录里的“让 CPU 占用率听你指挥”吸引力我的眼球.这一年 ...
- python 封装底层实现原理
事实上,python封装特性的实现纯属"投机取巧",之所以类对象无法直接调用私有方法和属性,是因为底层实现时,python偷偷改变了它们的名称. python在底层实现时,将它们的 ...
- 在Navicat新建Oracle表及用户
1. 打开Navicat,链接Oracle, 连接成功. 2. Ctrl+Q,进入查询,创建表空间. 输入create tablespace test datafile 'D:\Oracle\test ...
- centos7的新特性
1.修改主机名方式改变 centos6在/etc/ centos7使用命令hostnamectl set-hostname 主机名2.修改时间方式改变3.查看IP地址ifconfig不再支持改用ip4 ...
- python读取json文件
比如下图json数据,场景需要读取出wxid这项数据,然后传给后面的函数去使用 具体的脚本为 import json f =open('d:\\1024.json',encoding='utf-8') ...