Learn Multi platform PowerPC Assembly Programming... And feel the POWER!

The PowerPC processor is IBM's Desktop CPU comparable to the Intel x86 CPUs. Based on the previous POWER workstation CPUs, its RISC instruction set gave impressive speed and capabilities.

PowerPC became extremely popular around 2000, and was the basis for the Power Mac series, Gamecube, WII, Xbox360 and (to some extent) the PS3




If you want to learn POWERPC get the Cheatsheet! it has all the PowerPC commands, It will help you get started with ASM programming, and let you quickly look up commands when you get confused!

We'll be using ASW as our assembler for these tutorials
You can get the source and documentation for ASW from the official website HERE




Useful Documents
MPR601UM-01 PowerPC 601 Users Manual 1995
SR28-5124-01_The_PowerPC_Architecture_May94

Bit Order!

Because IBM hate us and want us to suffer, the official documents refer to the leftmost bit of a 32 bit value as bit 0 - on any other CPU it would usually be considered bit 31. We'll show both conventions - in diagrams 'IBM bits' will refer to MSB=0... 'bits' will refer to the more common MSB=31

We'll specify LSB and MSB to be clear... LSB 0 will be the rightmost bit...  MSB 31 will be the leftmost



IBM Documentation written by drunk madmen
Bit 31 is Least significant rightmost bit
Bit 0 is Most significant leftmost bit
IBM Bit:   0.1.2.........29.30.31
                    MSB --------- LSB
Everyone else in the entire world ever
Bit 0 is Least significant rightmost bit
Bit 31 is Most significant leftmost bit
Bit:   31.30.29.........2.1.0
           MSB --------- LSB


Most Significant Bts Least Significant Bits
Normal bit
 31   30   29   28   27   26   25   24   23   22   21   20   19   18   17   16   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0 
IBM Bit
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
Bit Value ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 512 256 128 64 32 16 8 4 2 1


The PowerPC Registers
All PowerPC registers are fully 32 bit.
There are 32 general purpose registers, and a few which have special purposes, and limited commands which can access their values

General Purpose Registers:
R0
Prologs / Hardwired Zero
R1 / SP
Used as Stack Pointer
R2 / RTOC
Table Of Contents pointer
R3 General Purpose - Arg1
R4 General Purpose - Arg2
R5 General Purpose - Arg3
R6 General Purpose - Arg4
R7 General Purpose - Arg5
R8 General Purpose - Arg6
R9 General Purpose - Arg7
R10 General Purpose - Arg8
R11 General Purpose
R12 General Purpose
R13 Reserved on 64 bit (free on 32 bit)
R14 General Purpose - NonVolatile
R15
General Purpose - NonVolatile
R16
General Purpose - NonVolatile
R17
General Purpose - NonVolatile
R18
General Purpose - NonVolatile
R19
General Purpose - NonVolatile
R20
General Purpose - NonVolatile
R21
General Purpose - NonVolatile
R22
General Purpose - NonVolatile
R23
General Purpose - NonVolatile
R24
General Purpose - NonVolatile
R25
General Purpose - NonVolatile
R26
General Purpose - NonVolatile
R27
General Purpose - NonVolatile
R28
General Purpose - NonVolatile
R29
General Purpose - NonVolatile
R30
General Purpose - NonVolatile
R31
General Purpose - NonVolatile
Floating Point Registers:
F0
General Purpose - Scratch reg
F1
General Purpose - Arg1
F2
General Purpose - Arg2
F3 General Purpose - Arg3
F4 General Purpose - Arg4
F5 General Purpose - Arg5
F6 General Purpose - Arg6
F7 General Purpose - Arg7
F8 General Purpose - Arg8
F9 General Purpose - Arg9
F10 General Purpose - Arg10
F11 General Purpose - Arg11
F12 General Purpose - Arg12
F13 General Purpose - Arg13
F14 General Purpose - NonVolatile
F15
General Purpose - NonVolatile
F16
General Purpose - NonVolatile
F17
General Purpose - NonVolatile
F18
General Purpose - NonVolatile
F19
General Purpose - NonVolatile
F20
General Purpose - NonVolatile
F21
General Purpose - NonVolatile
F22
General Purpose - NonVolatile
F23
General Purpose - NonVolatile
F24
General Purpose - NonVolatile
F25
General Purpose - NonVolatile
F26
General Purpose - NonVolatile
F27
General Purpose - NonVolatile
F28
General Purpose - NonVolatile
F29
General Purpose - NonVolatile
F30
General Purpose - NonVolatile
F31
General Purpose - NonVolatile
Special Registers:
LR
Link Register (Return Address)
CTR
CounT Register (for loop counts)
XER
eXcEption Register
FPSCR
Floating Point exception Register
CR
Condition register

Note:
There is no accessible PC register

The value in NonVolatile registers must be preserved by subs

R3-R10 are suggested for passing arguments to a sub

R0 cannot be always be used like other registers
Don't use R0 as a general maths register -
Some commands (like ADDI) treat R0 like a hardwired zero

R0 is used as a temp register during the 'Prolog/Epilog' of a sub (the Init and Cleanup of the stack during a sub.





Condition Register
The 32 bit condition register is split into 8x 4 bit parts.

IBM Bits
0-3
4-7
8-11
12-15
16-19
20-23
24-27
28-31
Purpose
CR0
CR1
CR2
CR3
CR4
CR5
CR6 CR7
Bits
31-28
27-24
23-20
19-16
15-12
11-8
7-4
3-0

CR2, CR3 and CR4, are Non Volatile, and must be preserved by subs

Each of the 4 CR bits for CR0-CR7 have the following purpose:
Bit
3
2
1
0
Meaning
Negative
(LT) 
Positive
(GT)
Zero
(EQ)
Summary
Overflow
(SO)

XER Register

use MFXER and MTXER to get or set the XER

IBM Bit
0 1 2  3-15  16-23 24 25-31
Meaning
SO
OV
CA
0
Byte compare
value
0 ByteCount
Bits 31 30 29 28-16 15-8 7 6-0


CA - Carry
OV - Overflow
SO - Summary Overflow
Byte Count - used by lswx or stswx


The PowerPC is typically a BIG Endian system, certainly in the case of the GameCube/WII, and apparently the Xbox 360

Though in fact the PowerPC can function in Little Endian mode

Addressing Modes
Mode Format Notes Example
Signed Immediate SIMM 16 bit signed Immediate addi rD,rA,SIMM
Unsigned Immediate UIMM 16 bit unsigned Immediate cmplwi crfD,rA,UIMM
Register rD,Ra,RB Leftmost param is destination (rD) add rD,rA,rB
Indirect with offset d(rA) Dest Address= value in rA + 16 bit signed immediate d stbu rS,d(rA)
Unconditional Address imm_addr 24 bit signed address b imm_addr
Conditional Address target_addr 14 bit signed address blt target
bc 12,O,target




























Branch Psuedo ops
BEQ Branch if Equal
BGE Branch if Greater or equal
BGT Branch if Greater Than
BLE Branch if Less or Equal
BLT Branch if Less Than
BNE Branch if Not Equal



Loading a 32 bit address

Our immediates can only be 16 bit, so we need to use LIS (Load Immediate Shifted <<16) and ORI

We can get the High and low 16 bit halves of an address with @h and @l... but we need to have a signed top value for LIS, which is provided by @ha... so to load our 32 bit label 'InfLoop' we use:

lis r3,[email protected]
ori r3,r3,[email protected]

Chars after a command

There are a few common suffixes to commands which enable options - of course, Not all suffixes are available to all commands!

. = Update Condition codes

z / ze = Zero extend (or add to zero on some commands)
a= algebraic (usually known as arithmetic Sign extended)
i = Immediate value
s = Shifted 16 bits  (top half of 32 bit value = 0xFFFF----  )

w= Word (32 bits)
h= Half (16 bits)
b = Byte (8 bits)


c (Maths) =  Carry - update CA of XER
c (Logical Ops) =  Compliment - Bit flip
e = Extend - add Carry and update Carry (CA of XER)
o = Overflow (use Overflow bit of XER)
u = Update (Postincrement register)
x = indeXed (use second register as address offset rather than immediate displacement)


+ = Branch prediction (Feeling positive - probably branch will occur!)
- = Branch prediction (Feeling Negative - Probably no branch!)