PowerPC栈帧分析

合集下载

基于powerPC的处理器修复技术研究

基于powerPC的处理器修复技术研究

基于power PC的处理器修复技术研究发布时间:2022-06-08T07:48:43.806Z 来源:《中国科技信息》2022年第4期作者:王闯张赟枫[导读] Power PC系列处理器的是一种具有升级性能好、功耗低优点的处理器。

王闯张赟枫江苏金陵机械制造总厂江苏南京210000摘要:Power PC系列处理器的是一种具有升级性能好、功耗低优点的处理器。

广泛应有与许多领域,但是在使用过程中也会存在各种各样的错误。

本篇文章通过讲述PowerPC系列处理器的工作原理,故障的排除等方面来分析经常出现的故障,供相关人员参考。

关键词:PowerPC处理器前言计算机的诞生和发展已经渗透到生活和生产的各个方面,Power PC在很多领域都扮演着非常重要的角色,比如通信、国防、工控领域,因为Power PC的众多优点,受到了许多设计师的喜爱,所以被应用到许多领域,随着众多处理器模块的出现,也出现了各种各样的故障,这些在生产、调试、维修中出现的故障,看着毫无关联,实际上有着紧密联系。

一、Power PC处理器简介Power PC诞生于1991年。

由IBM、苹果和摩托罗拉三个企业共同合作,,最终才成功开发。

1992年,第一代Power PC采用的单管密度是0.6 cm的生产工艺,其中,规模最大达到300万人。

目前Visca正在研究和制造Power PC处理器。

经过长时间的开发,该处理器已达到2GHz。

1998年,是另一个大发展时期,铜Power PC处理器出现开创了一个新的历史时代。

2000年代,IBM开始销售大量铜产品,如rs-6000-x80。

在逐步发展的过程中铜技术取代了铝技术。

铝技术在长期的发展中已经沿用了30年的。

铜技术的广泛的使用得到快速的发展,甚至在发展到,可以使硅芯片生产工艺达到了0.20微米的水平。

在不断的发展的过程中,集成在一个2亿个晶体管集成在一个电路中,大大提高了工作效率:工作电压目前是1.8V,相比于以前的工作电压为2.5V,大大减少了能耗,而且这种能耗的低压操作大大降低了芯片的损耗,更主要易于散热,并且少量大大提高了系统的稳定性。

riscv栈帧结构

riscv栈帧结构

riscv栈帧结构摘要:1.介绍RISC-V 栈帧结构的概念2.RISC-V 栈帧结构的组成部分3.RISC-V 栈帧结构的工作原理4.RISC-V 栈帧结构的优势和应用正文:RISC-V 是一种开源的处理器指令集架构(ISA),以其精简、模块化、可扩展的特点受到业界的关注。

在RISC-V 处理器中,栈帧结构扮演着至关重要的角色,它负责管理程序的运行状态和数据。

本文将详细介绍RISC-V 栈帧结构的相关知识。

RISC-V 栈帧结构主要由以下几个部分组成:1.栈指针(Stack Pointer, SP):栈指针用于存储栈顶地址,是栈帧结构的核心部件。

2.栈帧(Stack Frame):栈帧是栈中一段连续的内存区域,用于存储局部变量、函数参数和临时数据。

3.栈帧指针(Stack Frame Pointer, FP):栈帧指针用于存储当前栈帧的地址,方便在执行过程中切换不同的栈帧。

4.栈保护(Stack Protection):栈保护机制用于检测栈是否溢出,以保证程序的正常运行。

RISC-V 栈帧结构的工作原理如下:1.函数调用:当一个函数被调用时,RISC-V 处理器会为新函数分配一个新的栈帧,并将该函数的返回地址、局部变量等数据存入栈帧。

2.函数执行:在函数内部,可以通过修改栈指针和栈帧指针来访问和操作栈中的数据。

3.函数返回:当函数执行完毕后,RISC-V 处理器会根据返回地址弹出当前栈帧,恢复调用函数的执行状态。

RISC-V 栈帧结构具有以下优势:1.精简:RISC-V 栈帧结构相较于其他处理器架构更为精简,减小了处理器的硬件开销。

2.高性能:RISC-V 栈帧结构通过硬件实现,提高了栈操作的性能,尤其适用于高性能计算场景。

3.可扩展:RISC-V 栈帧结构可根据不同应用场景进行定制和扩展,满足各种处理器需求。

总之,RISC-V 栈帧结构作为一种关键的运行环境,有效地支持了RISC-V 处理器的运行和应用。

PowerPC处理器原理介绍

PowerPC处理器原理介绍

PowerPC处理器结构 PowerPC处理器体系结构概述
6、调试 PowerPC405处理器调试资源包括特殊调试模型,在 硬件和软件开发过程中,支持各种类型调试。这些调试包 括: 1)内部调试模式:ROM监控程序和软件调试器 2)外部调试模式:JTAG调试器 3)调试等待模式:处理器停下来允许服务中断 4)实时跟踪模式:事件触发用于实时跟踪
PowerPC处理器结构 PowerPC处理器体系结构概述
缓存控制器采用了最近使用的LRU的缓存行替换策略 。即缓存行被填充时,最近经常访问的缓存行被保留,而 其它均被替换。
指令缓存的功能包括:16KB,双向级关联(2-way set associative);奇偶检测和报告(只有Virtex-4);每缓存 行8字(32字节);提取行缓冲区;提供了来自提取行缓 冲区的取指命中;下一个顺序行的可编程预取到提取行缓 冲区;非缓存指令的可编程预取:全行(8字)/半行(4 字);提取行满时,非阻塞访问。
容。
PowerPC处理器结构 PowerPC处理器体系结构概述
PowerPC处理器是定点处理器,它与PowerPC UISA兼 容。PowerPC405 VEA和OEA支持大部分都可以用来实现 PowerPC405 Book-E的结构。图3.1给出了PowerPC处理器 的结构图。
PowerPC处理器结构 PowerPC处理器体系结构概述
PowerPC处理器结构 PowerPC处理器体系结构概述
4、指令和数据缓存 PowerPC处理器通过指令缓存单元ICU和数据缓存单 元DCU访问存储器。每个缓存单元包括: 1)PLB主接口 2)缓存阵列 3)缓存控制器; 对于CPU来说,对指令和数据缓存的命中是单周期的 存储器访问。处理缓存缺失,就是通过PLB向其它PLB设 备发出请求,比如外部存储器控制器。

Powerpc构架系统内核和内核模块调试.

Powerpc构架系统内核和内核模块调试.

Powerpc构架系统内核和内核模块调试Powerpc构架系统内核和内核模块调试类别:嵌入式系统作者:易松华,华清远见嵌入式学院深圳中心讲师。

说明:此文档的目标系统为freescale MPC8349E-mITX,对其他采用POWERPC,MIPS,ARM的芯片的系统亦具有参考意义。

此文档中内核调试为了简化,采用目标系统中的UBOOT初始化目标板,并通过UBOOT或者BDI2000加载内核到目标板的RAM中。

1.BDI2000配置:下面是MPC8349E-mITX的BDI2000配置文件,; BDI-2000 Configuration file for the MPC8349E-mITX ; Tip: If after a reset, the BDI-2000 fails to halt at 0x100, ; you may need to power-down the board for a few seconds. [INIT] ; we use UBOOT to initialize the board [TARGET] CPUTYPE 8349 JTAGCLOCK 1 ;STARTUP RESET STARTUP RUN BREAKMODE HARD STEPMODE HWBP BOOTADDR 0x00000100 ;If you're getting "Writing to workspace failed" errors during flash operations, ;then try uncommenting this line instead. This moves the FLASH windowto ;high memory, leaving low memory available for DDR. RCW0xb060a000 0x04040000 ;Set the HRCW to boot the image at 0xFE000000 MMU XLAT ;0xc0000000 PTBASE 0xf0 ; [HOST] IP 192.168.7.90 FILE $u-boot.bin LOAD MANUAL PROMPT 8349E-mITX-GP> DUMPitx-dump.bin [Flash] CHIPTYPE AM29BX16 CHIPSIZE 0x800000 BUSWIDTH 16 ;WORKSPACE 0x1000 FORMAT BIN0xfe000000 ;flash_image.bin is an image file of an entire 8MBflash region. ;Flash this file at 0xfe0000000 to restore all of flash. ;ERASE 0xFE000000 0x10000 127 ; 127 sectors @ 64KBeach ;ERASE 0xFE7F0000 0x2000 8 ; 8 sectors @ 8KB each ;FILE $flash_image.bin ;Use these lines if you just want to flash U-Boot ERASE 0xfe000000 0x10000? 4; Erase 384KB, each sector is64KB FILE? mpc8349e/u-boot131-mitx-gp.bin [REGS] FILE $reg8349e.def 以上配置文件的【HOST】段的IP要改为主机IP,关键的字段MMU XLAT 和PTBASE 是POWERPC和MIPS经常需要设置的,关于PTBASE的具体设置,超出本文范围,详细情况请参考BDI2000的手册 2.内核修改和配置为了能够调试内核,需要在内核中的Makefile中增加如下调试选项:CFLAGS 增加C代码调试选项-g –ggdb AFLAGS 增加汇编代码调试选项:-Wa,-L -gdwarf-2 去掉CFLAGS编译选项中-fomit-frame-pointer GCC的-fomit-frame-pointer选项是优化函数栈回溯(stack backtrace)的,我们调试的时候需要提供函数回溯能力,所以我们要去掉这个选项,当然,有的系统系统不受它的影响,或者说它不起作用,为了统一,我们统一去掉它。

PowerPC Figure – PPC入门与优化

PowerPC Figure – PPC入门与优化

PowerPC Figure – PPC入门与优化2007, Skywind背景介绍PowerPC于1991年IBM/MOTO/APPLE研制,大量应用于服务器(AIX / AS400系列及苹果系列服务器),家用游戏机(PS3, Wii, XBOX, GameCube),以及嵌入式(仅次于Arm/x86排第三)。

PowerPC核心在于开放系统软件标准,其应用范围仅次于x86,是除去x86外最值得开发者了解的体系。

不需要写出非常高效的代码,但要了解基本效率原则;不需要大规模开发PPC程序,但需要时能写几段、调试时能看懂哪里错了。

本文将从对比x86入手,引入RISC及PowerPC体系概念,向读者介绍该体系指令集,常用优化方法和交叉编译环境及模拟器的搭建等内容。

PowerPC基础知识1990年IBM时任总裁Kuehler说服了摩托罗拉公司和苹果公司与IBM公司共同参与制订PowerPC体系结构。

为了让AS/400也成为其中一员,1991 / 1992年罗彻斯特实验室开始为AS/400扩充并制订PowerPC的64位结构。

----《罗彻斯特城堡》大部分CPU指令集都可以分为:数据读写、数值计算、流程控制与设备管理四个部分,其中设备管理不属于介绍范围。

开放系统软件标准在于硬件/软件只要符合该标准都能在PowerPC下运行,也就是说先今有大量CPU虽然实现不一,但是他们在标准上都支持了PowerPC体系,使得开发与接口更为方便。

PPC使用RISC(精简指令集),指令字长都是32bit,一条Intel指令往往可以由多条PPC 指令组合表示。

Endian一般都是可调的,默认使用BE(Big Endian),同时PPC没有栈,也就是说应用程序需要自己实现相关操作。

常用术语介绍DWORD 64 BITS D QWORDPowerPC 其他名称X86 其他名称Branch JUMPCR+SPR EFLAGS常用寄存器类别说明补充通用寄存器GPRs R0 - R31 各32bitPPC64 中是64bit相当于EAX / EBX / ECX条件寄存器CR CR 32bit 被分为8段每段4位:LT,GT,EQ, SO CR0-CR7 各4位组成CR 相关运算需指明CRn连接寄存器LR 用作记录跳转地址32bitPPC64 中是64bit 常用作记录子程序返回的地址子程序调用指令在跳转前会改写特殊寄存器XER 记录溢出和进位标志作为CR的补充计数器CTR 32bit (PPC64中是64bit) 相当于ECX用途浮点寄存器FPRs FPR0 - FPR31 各64bit PPC32/PPC64的浮点都是64位浮点状态FPSCR 浮点运算类型和异常等同时可设置浮点异常捕获掩码问题1:如何加载32位立即数?在PPC下如何加载32位的立即数呢?RISC下PPC的每条指令都是4个字节定长。

PowerPC的外部中断处理

PowerPC的外部中断处理
在ISR寄存器中标记当前中断源正在被处理。处理器使用ISR寄存器,记 录所有正在被处理的中断源和当前最高的中断优先级别。 5. 所有的中断源都有可能引发外部中断。此时中断处理程序必须通过存放 在IACK寄存器中的硬件中断号,判断究竟是哪一个中断源引发的外部 中断,随后调用相应的中断服务例程,处理相应的中断事件。 6. 中断事件处理完毕后,处理器将对EOI寄存器进行写操作完成当前中断 ,并由中断寄存器PIC自动完成对ISR寄存器的维护,同时使用软件更 新CTPR寄存器为一个较低的值,以便其他中断进入。 7. 在程序员进行外部中断处理时,可以将CTPR寄存设为0,而由ISR寄存 器维护中断源的级别,并判断是否允许中断重入。
外部中断处理过程
© 2011 虹信通信
12
外部中断处理过程
处理器的内部或外部中断源有效时,会将相应的中断信号传递到中断控制
器PIC中,此时,中断控制器PIC会进行以下操作。
1. 处理器首先使用IPR寄存器暂存所有有效的内部及外部中断源。 2. 随后中断控制器PIC会对暂存在IPR寄存器中的中断源进行处理,并将 中断优先级别最高的中断源通过IS传递到IRR寄存器中。此时IRR寄存器 保存这个优先级别最高的中断源的硬件中断号和中断优先级别。 3. 如果在IRR寄存器中的存放中断源,其优先级高于CTPR和ISR寄存器中 存放的中断源,中断控制器PIC将使用int#或者cint#信号向处理器发出 中断请求。
© 2011 虹信通信
15
外部中断系统
1. Linux PowerPC对外部中断系统的初始化,包括一些重要结构空间的
分配内存并进行初始化。 2. 设备驱动程序的中断服务例程与外部中断处理系统的挂接。在设备驱
动程序初始化时,使用request_irq函数那个外部设备的中断服务例

elf符号表

ELF符号表结构(1)ELF文件中的符号表往往是文件中的一个段,段名一般叫".symtab"。

符号表的结构很简单,它是一个Elf32_Sym结构(32位ELF文件)的数组,每个Elf32_Sym结构对应一个符号。

这个数组的第一个元素,也就是下标0的元素为无效的"未定义"符号。

Elf32_Sym的结构定义如下:这几个成员的定义如表3-14所示。

表3-14符号类型和绑定信息(st_info)该成员低4位表示符号的类型(Symbol Type),高28位表示符号绑定信息(Symbol Binding),如表3-15、表3-16所示。

表3-15表3-16符号所在段(st_shndx)如果符号定义在本目标文件中,那么这个成员表示符号所在的段在段表中的下标;但是如果符号不是定义在本目标文件中,或者对于有些特殊符号,sh_shndx的值有些特殊,如表3-17所示。

表3-17符号值(st_value)我们前面已经介绍过,每个符号都有一个对应的值,如果这个符号是一个函数或变量的定义,那么符号的值就是这个函数或变量的地址,更准确地讲应该按下面这几种情况区别对待。

在目标文件中,如果是符号的定义并且该符号不是"COMMON块"类型的(即st_shndx不为SHN_COMMON,具体请参照"深入静态链接"一章中的"COMMON块"),则st_value表示该符号在段中的偏移。

即符号所对应的函数或变量位于由st_shndx指定的段,偏移st_value的位置。

这也是目标文件中定义全局变量的符号的最常见情况,比如SimpleSection.o中的"func1"、"main"和"global_init_var"。

在目标文件中,如果符号是"COMMON块"类型的(即st_shndx为SHN_COMMON),则st_value表示该符号的对齐属性。

arm 栈帧原理

arm 栈帧原理栈帧(stack frame)是计算机内存中用于存储函数调用和返回相关信息的一种数据结构。

它在函数调用过程中的栈(stack)上被动态创建和销毁。

每当一个函数被调用时,它的栈帧会被压入到栈的顶部,该栈帧保存了函数的局部变量、参数、返回地址以及其他相关信息。

栈帧的创建和销毁过程是自动完成的,由编译器生成的代码来管理。

在函数调用过程中,计算机会为每个函数创建一个独立的栈帧,以便存储函数执行所需的临时数据。

栈帧通常由以下几个主要部分组成:1. 局部变量区域:栈帧中的局部变量区域用于存储函数调用时所定义的局部变量。

这些局部变量在函数执行期间被分配和使用,当函数返回时,它们的内存空间将被释放。

2. 参数区域:栈帧中的参数区域用于存储函数调用时传递的参数。

这些参数可以是函数定义时所需的参数,也可以是编译器生成的临时参数。

3. 返回地址:栈帧中的返回地址用于存储函数调用结束后返回到调用点的位置。

当函数执行完毕后,程序会跳转到这个返回地址,继续执行调用点之后的代码。

4. 前一帧指针:栈帧中的前一帧指针(Frame Pointer,FP)指向上一个栈帧。

这个指针用于在函数调用发生时,寻找上一个栈帧,以便恢复上一个函数的执行。

5. 返回值:栈帧中的返回值用于存储函数的返回结果。

返回值可以是函数执行的任意类型,根据编程语言和函数定义的要求来决定。

栈帧的创建和销毁过程通常由编译器和计算机的执行引擎进行管理。

编译器在编译过程中会为每个函数生成对应的栈帧结构,并根据函数调用的情况在栈上动态分配和释放栈帧内存空间。

执行引擎会在函数调用发生时,将相关信息保存到栈帧中,并在函数返回时恢复现场以继续执行调用点的代码。

栈帧的设计和实现对于程序的性能和可靠性有着重要的影响。

合理的栈帧设计可以提高程序的执行效率,减少内存的占用。

同时,栈帧的正确创建和销毁也是确保程序正常运行的关键。

过多的栈帧创建和销毁可能会导致栈溢出或内存泄漏等问题。

PowerPC常用指令

查看文章PowerPC常用指令2009年05月14日星期四 22:20 指令缩写-------------------------st = storeld = loadr = rightl = left 或者 logicalw = wordu = updatem = movef = from 或者 fieldt = to 或者 thani = Immediateh = half wordz = zerob = branchn = andcmp = comparesub = subtractclr = clearcr = condition registerlr = link registerctr = couter registerstwu = STore Word witch Updatestwu r1, <-frame_size>(r1)--------------------------------在GDB/IDA汇编中通常写成stwu %sp, -0×20(%sp)意思是,先将SP放入到(SP-20)这个内存地址然后SP = SP - 20;从特殊寄存器取值的扩展助记符-------------------------mflr = Move From Link Registermflr rt 等同于 mfspr rt,8将连接寄存器的值放到RT一般是mflr %r0存值到特殊寄存器的扩展助记符-------------------------mtctr = Move To Counter Registermtctr rs 等同 mtspr 9,rs将RS的值放入到计数寄存器mtcrf = Move to Condition Register Fields mtcrf FXM, RS按照掩码FXM,复制Rs的内容到CRFXM是8位,控制 RS的32位(8组,共32位)复制过去,也就是说 FXM的1位,可以控制Rs的4位一位掩码控制一组CR条件寄存器扩展助记符-------------------------crclr = Control Register CLeaRcrclr bx 等同于 crxor bx, bx, bx 作用是将条件寄存器相应的位清零例如crclr so 等同于 crxor 3, 3, 3 将CR0的SO位(第3位)清零crclr 4*cr3+eq 等同于 crxor 14, 14, 14 将CR3的EQ位清零比较指令-------------------------cmpli = Compare Logical Immediatecmplwi bf, ra, ui 等同于 cmpli bf, 0, ra, uiCompare Logical Word Immediate所谓逻辑比较,就是同无符号整数比较存储指令-------------------------sth = Store Half 并且是存储高位 (16-31位)载入指令-------------------------lhz = Load Half and Zero 载入半字并将高16位清零lwzx = Load Word and Zero Indexed 意思是 lwzx RT, RA, RB (Ra+Rb就是地址)跳转-------------------------bccl = bctrl (有别名的助记符)Branch Conditional to Count Register条件跳转到计数寄存器指定的地址逻辑操作-------------------------ori 或者 oril = OR Immediate 同16位立即数进行或操作循环掩码操作循环左移然后进行掩码操作是PowerPC指令集的精华,包含了一组非常强大的指令集移位指令-------------------------slwi = Shift left immediate 左移几位(位数用立即数表示)rotlwi = Rotate left immediate 循环左移抽取-------------------------extrwi = Extract and right justify immediate例如 extrwi RX, RY, 1, 0等同于 rlwinm RX, RY, 1, 31, 31rlwinm or rlinm (Rotate Left Word Immediate Then AND with Mask)清除-------------------------clrlwi = Clear left immediate怪异清除clrlslwi = Clear (Left Word) and Shift Left clrlslwi %r0, %r0, 24,8 等同于rlwinm RA, RS, 24-8, 31-24 =rlwinm Ra, Rs, 16, 7rlwinm RA, RS, SH, MB, ME将R0向左循环移动掩码是 [8, 15]影响CR的运算-------------------------如果Overflow Exception(OE)设置1,那么结果影响定点异常寄存器的Summary Overflow(SO)和 Overflow(OV),助记符是后面加o, addo如果Record(Rc)设置1,那么结果影响Less Than(LT) zero, Greater Than (GT) zero, Equal To (EQ) zero,和Summary Overflow (SO)等条件寄存器CR助记符是后面加”点” add.算术运算-------------------------注意方向subf = Subtract From 注意,被减数是后面的那个寄存器计数器循环在扩展助记符中,计数寄存器的语义可以通过在b后面立即添加dz或 dnz来指定。

powerpc异常

1. 异常类型00Critical Interrupt 来自于外部中断控制器,具有较高的优先级01Machine Check 严重的内部状态错误,如Cache 数据的校验失败02 Data Storage 数据读写异常,如:用户态读一个非用户态的页(UR=0)03 Instruction Storage 读指令异常,如:用户态时取一个用户态不可执行的页(UX=0)04External Interrupt 来自于外部中断控制器05 Alignment 非对齐访问异常06Program 程序异常,如:执行非法指令,用户态执行特权指令07 Floating-Point unavailable 在无浮点部件的CPU 上执行浮点指令即会触发此异常08System call 系统调用09 Auxiliary Processor Unavailable 在无协处理器的CPU 上执行协处理器指令即触发此异常10 Decrementer DEC 寄存器归零异常,DEC 是一个内部时钟计数器,Linux 用之实现时钟中断11 Fixed-interval timer interrupt12Watchdog timer interrupt13Data TLB error 数据TLB Miss 异常14Instruction TLB error 指令TLB Miss 异常15Debug 调试异常,用于支持调试16 - 31 Reserved for future use 保留给将来体系结构升级用32 - 63 Allocated for implementation-dependent use 具体实现相关其中0,1,12,15 为Critical Exception,当其发生时,使用CSRR0 & CSRR1 保存当前PC 或(PC + 4) 和MSR;其他异常发生时,则使用SRR0 & SRR1 保存当前PC 或(PC + 4) 和MSR可以看到BOOKE 体系结构层面规定的异常即为前16 个,这其中的有些异常是个笼统的抽象(比如Data Storage 就需要区分是读还是写导致的),为了更细地描述发生异常的原因,PowerPC 引入了一个ESR (Exception Syndrome Register),让硬件在异常发生时,在其中指出更具体的原因。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

PowerPC栈帧分析 1 .PowerPC寄存器的使用规则 通用寄存器的用途: r0 在函数开始(function prologs)时使用。 r1 堆栈指针,相当于ia32架构中的esp寄存器,idapro把这个寄存器反汇编标识为sp。 r2 内容表(toc)指针,idapro把这个寄存器反汇编标识为rtoc。系统调用时,它包含系统调用号(这个好像跟系统有关吧)。 r3 作为第一个参数和返回值。 r4-r10 函数或系统调用开始的参数。 r11 用在指针的调用和当作一些语言的环境指针。 r12 它用在异常处理和glink(动态连接器)代码。 r13 保留作为系统线程ID。 r14-r31 作为本地变量,非易失性。 专用寄存器的用途: lr 链接寄存器,它用来存放函数调用结束处的返回地址。 ctr 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。 xer 定点异常寄存器,存放整数运算操作的进位以及溢出信息。 msr 机器状态寄存器,用来配置微处理器的设定。 cr 条件寄存器,它分成8个4位字段,cr0-cr7,它反映了某个算法操作的结果并且提供条件分支的机制。 2.栈帧的使用规则 PowerPC寄存器没有专用的Pop,Push指令来执行堆栈操作,所以PowerPC构架使用存储器访问指令stwu,lwzu来代替Push和Pop指令。PowerPC处理器使用GPR1来将这个堆栈段构成一个单向链表,这个单链表的每一个数据成员,我们称之为堆栈帧(Stack Frame),每一个函数负责维护自己的堆栈帧。 PowerPC体系结构中栈的增长方向是从高地址到低地址,堆的增长方式是从低地址到搞地址,当两者相遇时就会产生溢出。 堆栈帧的格式如下: 各部分名词解释: 函数参数域(Function Parameter Area):这个区域的大小是可选的,即如果如果调用函数传递给被调用函数的参数少于六个时,用GPR4至GPR10这个六个寄存器就可以了,被调用函数的栈帧中就不需要这个区域;但如果传递的参数多于六个时就需要这个区域。 局部变量域(Local Variables Area):通上所示,如果临时寄存器的数量不足以提供给被调用函数的临时变量使用时,就会使用这个域。 CR寄存器:即使修改了CR寄存器的某一个段CRx(x=0至7),都有保存这个CR寄存器的内容。 通用寄存器GPR:当需要保存GPR寄存器中的一个寄存器器GPRn时,就需要把从GPRn到GPR31的值都保存到堆栈帧中。 浮点寄存器FPR:使用规则共GPR寄存器。 3.?PowerPC的汇编指令和栈操作 PowerPC寄存器没有专用的push和pop指令来执行堆栈操作,所以PowerPC构架使用存储器访问指令stwu、lwzu来代替push和pop指令。 4.函数执行时栈帧的建立与消亡过程 函数栈的建立与消亡过程如下图所示: 4.1函数栈的建立与消亡过程说明 如前所属,PowerPC体系结构中栈的增长方向是从高地址到低地址,故形成过程可以概括为如下几点: 1) 调用函数r1指向栈顶(SP),用间接寻址方式分配一定大小栈空间; 2) r31指向栈顶,以r31为基值将参数压入栈内; 3) 进入被调函数,跳转到被调函数的SP处; 4) 被调函数同样进行栈分配及参数压栈操作; 5) 被调函数执行完毕之后,跳转LR,返回到被调用处的下一条指令,继续后续操作(此时的SP即为调用函数的SP) 4.2举例说明栈操作过程 以下以一个简单的函数调用,说明PowerPC栈的操作过程。 函数例子如下: int calltest2( int a) { int t1=5; int t2 = 6; int result =0; char * p =0; *p =a; } int calltest1( int a) { int t1=3; int t2 = 4; int result =0; result = calltest2( t2); t1 =3; } void calltest( ) { int t1=7; int t2 = 9; int result =0; result = calltest1( t1); t1 =3; }

利用反汇编工具,生成汇编代码及分析如下:

int calltest2( int a) { Calltest2栈帧建立分析: stwu r1,-48(r1):分配48字节的栈帧,r1指向栈顶;(powerpc省略了EBP,所以一上来即进行一次间接寻址) stw r31,44(r1):保存r31的原值,以后恢复; or r31,r1,r1:让r31指向栈顶r1(r31=r1 or r31) stw r3,8(r31):第一个形参 0x401d4f0 calltest2: stwu r1,-48(r1) 0x401d4f4 +0x004: stw r31,44(r1) 0x401d4f8 +0x008: or r31,r1,r1 0x401d4fc +0x00c: stw r3,8(r31) 局部变量赋值:li r0 5(t1,t2.result) int t1=5; 0x401d500 +0x010: li r0,0x5 # 5 0x401d504 +0x014: stw r0,12(r31) int t2 = 6; 0x401d508 +0x018: li r0,0x6 # 6 0x401d50c +0x01c: stw r0,16(r31) int result =0; 0x401d510 +0x020: li r0,0x0 # 0 0x401d514 +0x024: stw r0,20(r31) char * p =0; 0x401d518 +0x028: li r0,0x0 # 0 0x401d51c +0x02c: stw r0,24(r31) 加载函数调用参数到r9 *p =a; 0x401d520 +0x030: lwz r9,24(r31) 0x401d524 +0x034: lbz r0,11(r31) 保存r9到r0 0x401d528 +0x038: stb r0,0(r9) } r11=r1,r31=r11-4=r1-4,恢复r31的值 0x401d52c +0x03c: lwz r11,0(r1) 0x401d530 +0x040: lwz r31,-4(r11) 0x401d534 +0x044: or r1,r11,r11 blr:跳转到LR地址,返回calltest1中调用calltest2的下一条指令地址0x401d57c的继续指向 0x401d538 +0x048: blr int calltest1( int a) { 0x401d53c calltest1: stwu r1,-48(r1) 将LR内容存入r0(存在函数调用时需要用到LR,用来存放函数调用结束处的返回地址) 0x401d540 +0x004: mfspr r0,LR 0x401d544 +0x008: stw r31,44(r1) 0x401d548 +0x00c: stw r0,52(r1) 0x401d54c +0x010: or r31,r1,r1 0x401d550 +0x014: stw r3,8(r31) 局部变量赋值(t1,t2,result) int t1=3; 0x401d554 +0x018: li r0,0x3 # 3 0x401d558 +0x01c: stw r0,12(r31) int t2 = 4; 0x401d55c +0x020: li r0,0x4 # 4 0x401d560 +0x024: stw r0,16(r31) int result =0; 0x401d564 +0x028: li r0,0x0 # 0 0x401d568 +0x02c: stw r0,20(r31) 函数调用 result = calltest2( t2); 0x401d56c +0x030: lwz r3,16(r31) 0x401d570 +0x034: bl 0x401d4f0 # calltest2 0x401d574 +0x038: or r0,r3,r3 0x401d578 +0x03c: stw r0,20(r31) t1 =3; 0x401d57c +0x040: li r0,0x3 # 3 0x401d580 +0x044: stw r0,12(r31) } 0x401d584 +0x048: lwz r11,0(r1) 0x401d588 +0x04c: lwz r0,4(r11) 0x401d58c +0x050: mtspr LR,r0 0x401d590 +0x054: lwz r31,-4(r11) 0x401d594 +0x058: or r1,r11,r11 返回calltest函数的下一条指令地址0x401d5d8的继续指向 0x401d598 +0x05c: blr void calltest( ) { 0x401d59c calltest: stwu r1,-48(r1) 0x401d5a0 +0x004: mfspr r0,LR 0x401d5a4 +0x008: stw r31,44(r1) 0x401d5a8 +0x00c: stw r0,52(r1) 0x401d5ac +0x010: or r31,r1,r1 int t1=7; 0x401d5b0 +0x014: li r0,0x7 # 7 0x401d5b4 +0x018: stw r0,8(r31) int t2 = 9; 0x401d5b8 +0x01c: li r0,0x9 # 9 0x401d5bc +0x020: stw r0,12(r31)

相关文档
最新文档