Instructions
|
Stack FrameExample when using frame pointer and two local variables:
my_sub: # Adds 1 to first argument # Prologue stwu %r1,-16(%r1) # "push" mflr %r0 # r0 = link register stw %r0,20(%r1) # Save link register # Body of subroutine: addi %r3, %r3, 1 # Epilogue lwz %r0,20(%r1) mtlr %r0 addi %r1, %r1, 16 # "pop" blr |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Constants, Registers, MemoryConstants can just be written normally. HOWEVER, be aware that if an instruction expects a register, it'll treat "4" as a register number, not a constant! Weirdness: if a constant is more than 16 bits long, you can't load it in one instruction.Registers can actually just be written as a number, like "3" (meaning register r3). To be clearer, preceed any register name with "%r"; for example, "%r3" means register r3. This means "add 3,4,5" is the same as "add %r3, %r4, %r5". Use the "i" (immediate) form of the instruction if you want to put in a constant, or use "li" to load the constant into a register. All memory access is via the load and store routines--you *can't* just get to a random memory location from any instruction. |
Registers%r1 is the stack pointerReturn value in %r3 First 8 integer arguments are in %r3 through %r10; remainder on stack. Free for use (no save needed): %r0, and %r3 through %r12 Must be saved: %r13 through %r31 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Floating PointLoad and store from memory with lfs/lfd (load float single/double) stfs, stfd.Arithmetic instructions start with "f", like "fadd", "fmul", "fmadd", "fdiv". There are both single- and double-precision versions, with the single-precision versions ending in "s" (like fadds), but they both use the same register set. Weird instructions: "fres" (computes approximate 1.0/x); "frsqrte" (1.0/sqrt(x), approximate). |
Floating Point RegistersRegisters are all 64-bit doubles.Floating point args are in %f1-%f13 %f0-%f13 are free for any use %f14-%f31 must be saved Return value goes in %f1 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Common ErrorsError: operand out of range (123 not between 0 and 31)You passed in some constant (here 123); the assembler expected a register. Error: operand out of range (100000 not between -32768 and 32767) You passed in a constant that was too big. Use "li" and "addis" to stick the constant together from 16-bit pieces (or just choose another constant!) |