PowerPC Assembler Learning

来源:互联网 发布:mysql 级联删除表 编辑:程序博客网 时间:2024/06/02 03:03

PowerPC Assembler Learning

由于某些需要,反汇编了PowerPC的一些代码进行研究。
 class A{
 public:
A(){}  
~A(){} 
 int x;
};     
              
 int main(A& n){
   int b;      
   A a;        
   b++;        
   a = n;      
  return 1;    
 }             
test.o:     file format elf32-powerpc                           
                                                                
Sections:                                                       
Idx Name          Size      VMA       LMA       File off  Algn  
  0 .text         00000110  00000000  00000000  00000034  2**2  
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE  
  1 .data         00000000  00000000  00000000  00000144  2**0  
                  CONTENTS, ALLOC, LOAD, DATA                   
  2 .bss          00000000  00000000  00000000  00000144  2**0  
                  ALLOC                                         
  3 .comment      00000020  00000000  00000000  00000144  2**0  
                  CONTENTS, READONLY                            
Disassembly of section .text:                                   
test__FR1A():                                                   
00000000 <test__FR1A> 94 21 ff d8  stwu r1,-40(r1)              
00000004 <test__FR1A+4> 7c 08 02 a6  mflr       r0              
00000008 <test__FR1A+8> 93 a1 00 1c  stw        r29,28(r1)      
0000000c <test__FR1A+c> 93 c1 00 20  stw        r30,32(r1)      
00000010 <test__FR1A+10> 93 e1 00 24  stw       r31,36(r1)      
00000014 <test__FR1A+14> 90 01 00 2c  stw       r0,44(r1)      
00000018 <test__FR1A+18> 7c 3f 0b 78  mr        r31,r1          
0000001c <test__FR1A+1c> 90 7f 00 08  stw       r3,8(r31)       
00000020 <test__FR1A+20> 38 1f 00 10  addi      r0,r31,16       
00000024 <test__FR1A+24> 7c 03 03 78  mr        r3,r0           
00000028 <test__FR1A+28> 48 00 00 c1  bl        000000e8 <__1A> 
0000002c <test__FR1A+2c> 81 3f 00 0c  lwz       r9,12(r31)     
00000030 <test__FR1A+30> 38 09 00 01  addi      r0,r9,1         
00000034 <test__FR1A+34> 7c 09 03 78  mr        r9,r0           
00000038 <test__FR1A+38> 91 3f 00 0c  stw       r9,12(r31)      
0000003c <test__FR1A+3c> 81 3f 00 08  lwz       r9,8(r31)       
00000040 <test__FR1A+40> 80 09 00 00  lwz       r0,0(r9)        
00000044 <test__FR1A+44> 90 1f 00 10  stw       r0,16(r31)      
00000048 <test__FR1A+48> 3b a0 00 01  li        r29,1           
0000004c <test__FR1A+4c> 38 1f 00 10  addi      r0,r31,16       
00000050 <test__FR1A+50> 7c 03 03 78  mr        r3,r0           
00000054 <test__FR1A+54> 38 80 00 02  li        r4,2            
00000058 <test__FR1A+58> 48 00 00 2d  bl        00000084 <_$_1A>
0000005c <test__FR1A+5c> 7f a3 eb 78  mr        r3,r29          
00000060 <test__FR1A+60> 48 00 00 04  b 00000064 <test__FR1A+64>
00000064 <test__FR1A+64> 81 61 00 00  lwz       r11,0(r1)       
00000068 <test__FR1A+68> 80 0b 00 04  lwz       r0,4(r11)       
0000006c <test__FR1A+6c> 7c 08 03 a6  mtlr      r0              
00000070 <test__FR1A+70> 83 ab ff f4  lwz       r29,-12(r11)    
00000074 <test__FR1A+74> 83 cb ff f8  lwz       r30,-8(r11)     
00000078 <test__FR1A+78> 83 eb ff fc  lwz       r31,-4(r11)     
0000007c <test__FR1A+7c> 7d 61 5b 78  mr        r1,r11          
00000080 <test__FR1A+80> 4e 80 00 20  blr                       
_$_1A():                                                        
00000084 <_$_1A> 94 21 ff e8  stwu      r1,-24(r1)              
00000088 <_$_1A+4> 7c 08 02 a6  mflr    r0                      
0000008c <_$_1A+8> 93 81 00 08  stw     r28,8(r1)               
00000090 <_$_1A+c> 93 a1 00 0c  stw     r29,12(r1)              
00000094 <_$_1A+10> 93 c1 00 10  stw    r30,16(r1)              
00000098 <_$_1A+14> 93 e1 00 14  stw    r31,20(r1)              
0000009c <_$_1A+18> 90 01 00 1c  stw    r0,28(r1)               
000000a0 <_$_1A+1c> 7c 3f 0b 78  mr     r31,r1                  
000000a4 <_$_1A+20> 7c 7d 1b 78  mr     r29,r3                  
000000a8 <_$_1A+24> 7c 9c 23 78  mr     r28,r4                  
000000ac <_$_1A+28> 57 80 07 fe  clrlwi r0,r28,31               
000000b0 <_$_1A+2c> 2c 80 00 00  cmpwi  cr1,r0,0                
000000b4 <_$_1A+30> 41 86 00 10  beq    cr1,000000c4 <_$_1A+40> 
000000b8 <_$_1A+34> 7f a3 eb 78  mr     r3,r29                  
000000bc <_$_1A+38> 48 00 00 01  bl     000000bc <_$_1A+38>     
000000c0 <_$_1A+3c> 48 00 00 04  b      000000c4 <_$_1A+40>     
000000c4 <_$_1A+40> 81 61 00 00  lwz    r11,0(r1)               
000000c8 <_$_1A+44> 80 0b 00 04  lwz    r0,4(r11)               
000000cc <_$_1A+48> 7c 08 03 a6  mtlr   r0                      
000000d0 <_$_1A+4c> 83 8b ff f0  lwz    r28,-16(r11)            
000000d4 <_$_1A+50> 83 ab ff f4  lwz    r29,-12(r11)            
000000d8 <_$_1A+54> 83 cb ff f8  lwz    r30,-8(r11)             
000000dc <_$_1A+58> 83 eb ff fc  lwz    r31,-4(r11)             
000000e0 <_$_1A+5c> 7d 61 5b 78  mr     r1,r11                  
000000e4 <_$_1A+60> 4e 80 00 20  blr                            
__1A():                                                         
000000e8 <__1A> 94 21 ff f0  stwu       r1,-16(r1)              
000000ec <__1A+4> 93 e1 00 0c  stw      r31,12(r1)              
000000f0 <__1A+8> 7c 3f 0b 78  mr       r31,r1                  
000000f4 <__1A+c> 7c 60 1b 78  mr       r0,r3                   
000000f8 <__1A+10> 7c 03 03 78  mr      r3,r0                   
000000fc <__1A+14> 48 00 00 04  b       00000100 <__1A+18>      
00000100 <__1A+18> 81 61 00 00  lwz     r11,0(r1)               
00000104 <__1A+1c> 83 eb ff fc  lwz     r31,-4(r11)             
00000108 <__1A+20> 7d 61 5b 78  mr      r1,r11                  
0000010c <__1A+24> 4e 80 00 20  blr                              
 
网络上零零散散找了些资料,可惜都很难符合要求,只好自己慢慢啃这段代码了。
              
主要的目的就是弄清楚 PowerPC得堆栈以及32个寄存器的用途了。
Registers at time of exception:
r00: 00003809 r01: 04c17fe0 r02: 00000000 r03: 00000000
r04: 00003130 r05: 00ed8f5c r06: 00000014 r07: 0135d61c
r08: 00000000 r09: ffffffff r10: 00000004 r11: 04c17f98
r12: 00000000 r13: 00000000 r14: 00000000 r15: 00000000
r16: 00000000 r17: 00000000 r18: 00000000 r19: 03f05597
r20: 00000000 r21: 00000000 r22: 00000000 r23: 029e0de8
r24: 00000000 r25: 0000286d r26: 00008200 r27: 03efd398
r28: 00000000 r29: 000a4538 r30: 00000000 r31: 03044940
msr: 0008b130 lr:  00003809 ctr: 00000000 pc:  00003808
cr:  42000082 xer: 20000000 dar: 00000000 dsisr:00000000
fpscr:82028070
Code traceback:
Stack Current: 1344 bytes
Stack Maximum: 2296/20464

04c17ff0: 04c19a10 0086548c *......T.*
04c17ff8: 00000000 00000000 *........*
04c18000: 00010000 01bd93a0 *........*
04c18008: 04c18010 00f22350 *......#P*
04c18010: 04c18050 00f2370c *...P..7.*
04c18018: 00000000 00000000 *........*
04c18020: 00000000 00000000 *........*
04c18028: 0013b794 00000000 *........*
04c18030: 00000000 00000000 *........*
04c18038: 00000000 04c18270 *.......p*
04c18040: 01bdcbb8 00000000 *........*
04c18048: 029e18c8 01bd93a0 *........*
04c18050: 04c18068 00f21818 *...h....*
04c18058: 04c18188 00000000 *........* 
 
 
可惜没有很好的源码调试debug工具,GDB也不知道如何在这个平台运行起来,所以只好做蠢人做的事情了。
--------------- reference from Net-work-------------------------
PowerPC的应用级寄存器分为三类:通用寄存器(general-purpose register,GPR)、浮点寄存器(floating-point register [FPR] 和浮点状态与控制寄存器 [Floating-Point Status and Control Register,FPSCR])和专用寄存器(special-purpose register,SPR)。gdb里的info registers能看到38个寄存器,下面主要介绍这几个常用的寄存器:
  
  通用寄存器的用途:
  
  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,它反映了某个算法操作的结果并且提供条件分支的机制。
  
  寄存器r1、r14-r31是非易失性的,这意味着它们的值在函数调用过程保持不变。寄存器r2也算非易失性,但是只有在调用函数在调用后必须恢复它的值时才被处理。
  
  寄存器r0、r3-r12和特殊寄存器lr、ctr、xer、fpscr是易失性的,它们的值在函数调用过程中会发生变化。此外寄存器r0、r2、r11和r12可能会被交叉模块调用改变,所以函数在调用的时候不能采用它们的值。
  
  条件代码寄存器字段cr0、cr1、cr5、cr6和cr7是易失性的。cr2、cr3和cr4是非易失性的,函数如果要改变它们必须保存并恢复这些字段。
--------------------------------------------------------------------------------------------------
首先说明一下 PowerPC的栈管理,堆管理估计要以后再去研究了。
R01是PowerPC的栈指针,R01里面存在就是前一个栈指针,PowerPC就是靠R01把整个栈链起来的。
 
每段程序的入口都会执行如下的操作:
stwu r1 ,-56(r1)
56是系统分配这个函数的栈大小,stw,lwz 分别是PowerPC作为RISC体系的写读内存命令。
stw RA, D(RS) store RA into MEM[ RS+D ], u 表示同时update RA,指向 MEM.
栈的分布为:
             |                        |     ^
sp----> +-----------------+     | 栈
             | Linkage Area   |     | 增
            +------------------+    | 长
             |Para Area         |     | 方
            +------------------+    | 向
 
链接区从上往下存储内容为(地址递增) 前一个SP (紧跟着 参数区末), LR (  调用函数PC).....
参数区为argv(一般都是调用函数传到r3中)/返回值的指针,局部变量,然后到前一个sp指针的区域都是用来保存R14 -- R31的值,(依据函数使用情况而保存,有些只需要R31而已。
such as:
Sp1->+------+
          | Sp0 |
          +------+
           | LR   |
          +------+
           |R3     |
          +------+
           |R30   |
          +------+
           |R31   |
Sp0->+------+
每个函数除了要保存这些通用寄存外。
在调用子函数前,都会做一些保存的操作:
保存lr,这个是指向父函数的。
mflr  r0;  // lr -> r0
stw r0,44(r1) // r0 /lr -> sp0+4,sp1栈大小为40
把必要的参数传到r3(,r4)
接着用 bl (blance with LR) 进入子函数。
bl op // pc->lr, op -> pc;
子函数返回时,在执行blr (lr -> pc )前需要
恢复r31-rX,   lwz r11,0(r1); lwz r31, -4(r11);
恢复sp,      mr r1,r11.  
在函数返回后,当前函数需要恢复lr,以便pc回到正确的父函数函数执行点。
lwz r11,0(r1); //r11 = SP0
lwz r0, 4(r11);
mtlr r0;  //recover lr.
.... //recover r31 ~ rx
mr r1,r11 //recover sp
blr.
回到需要研究的case上:
有下面几个疑问:
1。为什么sp会被修改?从代码看,sp不可能被显式更改。
2。lr跟pc相等的情况并不是很多,只要在调用跟返回时。例子中更是等于当前sp+4,更是只是确定只有返回了。
3。为什么当前的pc非法会影响到另外个一个task,而负责audit的task是如何来判断呢?
 
 
 参考资料:
1。Simplified PowerPC Instruction Set http://pds.twi.tudelft.nl/vakken/in1200/labcourse/instruction-set/ 
2。Mac OS X Assembler Reference http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/index.html?http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/PPCInstructions/chapter_6_section_6.html
3。Assembler Language Reference http://inetsd01.boulder.ibm.com/pseries/cs_CZ/aixassem/alangref/mastertoc.htm#mtoc
 
原创粉丝点击