PowerPC Assembly

CS 301 Lecture, Dr. Lawlor

See also:
Generally:
Other than that, PowerPC is pretty dang similar to x86.

Examples

"%r3" is the return value register.  So if you "li" (Load an Immediate) into "%r3", and then return with a "blr" (Branch to the Link Register), you'll return a value:
li %r3, 12345
blr

(Try this in NetRun now!)

The "add" instruction on PowerPC takes *three* arguments, so you can add any two registers and put the result into a third register:
li %r4,10
li %r7,20
add %r3,%r7,%r4
blr

(Try this in NetRun now!)

Here's a multiply, which is "mullw" (MULtiply and extract Low Word):
li %r4,10
li %r7,20
mullw %r3,%r7,%r4
blr

(Try this in NetRun now!)

The "addi" instruction adds a *constant* (an "immediate" value) to a register.
li %r4,10
li %r7,20
addi %r3,%r7,5
blr

(Try this in NetRun now!)

Note there *is* no "addm" instruction that adds a register and a value from memory.  This is typical of a RISC machine like PowerPC.  To get to memory, you have to use the dedicated "stw" (STore 32-bit Word) and "lwz" (Load 32-bit Word and Zero the high bits on a 64-bit machine) instructions.  Here I'm storing %r4 into some space in the "red zone" directly below the stack pointer, then reading it back into %r3 for return:

li %r4,12345
stw %r4,-16(%r1)
lwz %r3,-16(%r1)
blr

(Try this in NetRun now!)

The most frustrating thing about PowerPC (and RISC machines generally) is loading up constants.  Here's how you load up "0xdeadbeef": start by loading the high 16 bits (add-immediate-with-16-bit-shift plus zero), then OR in the low 16 bits.  You have to do this because it's not possible to fit a 32-bit constant in a 32-bit instruction, and *all* PowerPC instructions are a fixed 32 bits.
addis %r3,%r0,0xdead
ori %r3,%r3,0xbeef
blr

(Try this in NetRun now!)

PowerPC stores the return address in a special register called the "link register".  If you want to call another function, you need to save your own caller's return address (in the link register) somewhere.  Here, I'm saving the address to an unused register, but usually you'd save the old link register on the stack:
mflr %r7  # Save our old Link Register into register 7 (which my_func doesn't use)

bl my_func # Save our return address into the Link Register and jump to my_func

mtlr %r7 # Restore our Link Register from r7
blr


my_func:
li %r3,1234
blr

(Try this in NetRun now!)


The bottom line?  PowerPC assembly is *exactly* like x86 assembly in all the important ways: you've got some CPU instructions that operate on registers and memory.  There are small differences, but they're actually pretty superficial--computers everywhere are the same, deep down!