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
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
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
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是非易失性的,函数如果要改变它们必须保存并恢复这些字段。
--------------------------------------------------------------------------------------------------
通用寄存器的用途:
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.
在调用子函数前,都会做一些保存的操作:
保存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。为什么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
- PowerPC Assembler Learning
- PowerPC
- PowerPC
- PowerPC
- ARM Assembler VS GNU Assembler
- PowerPC简介
- powerpc资源
- PowerPC 有感
- powerpc gpio
- PowerPC 堆栈
- PowerPC汇编语言
- PowerPC汇编语言
- PowerPC OpenFirmware
- POWERPC中断
- Powerpc也开核
- PowerPC DevTree
- PowerPC简介
- PowerPC介绍
- 用Socket实现的多线程类邮件服务器,朋友的一个作业题
- WCF分布式开发必备知识(2):.Net Remoting
- 关注养生 必做7个小动作
- LINQ to SQL Serialization(webservice)
- Html元素
- PowerPC Assembler Learning
- XML初步到精通
- SWT,Text的回车事件的处理代码
- 2008年12新增网站
- 什么叫做实体经济危机?
- 为老板上班的人必看,请挖一口属于自己的井
- 好网址
- 无处不在的二八原理[1]:在软件开发中的应用
- GridView和DataList实现鼠标移到行行变色