Assemble + Disassemble PPC ASM with DevKitPPC (Linux)
#1
Assemble + Disassemble PPC ASM with DevkitPPC (Linux)

NOTE: This guide is for Linux users only.

NOTE: This is NOT meant to replace any assembler+disassembler regarding ASM codes (such as WiiRDGUI, PyiiASMH), it's just for general PowerPC ASM assembling+disassembling.

Requirements-
Have Devkit installed and working (For Debian, I have an Installation Guide - http://mkwii.com/showthread.php?tid=1200)

Overview-
This guide will teach you how to assemble ASM instructions (in a text file) to a final output in your terminal screen. This guide assumes your ASM txt file is 'example.s' in the your home user account directory. 

This guide will also teach you how to disassemble ASM instructions of a binary file and display the source on your terminal screen.



TO ASSEMBLE ASSEMBLY (into binary file)

1. Navigate to DevkitPPC binutils

Open a terminal to where you installed your Devkit (for me, I installed mines to /opt)

cd /opt/devkitpro/devkitPPC/bin

2. Assemble the ASM instructions to object code

./powerpc-eabi-as -mregnames -mbroadway /home/yourusername/example.s -o /home/yourusername/objectcode.o

3. Convert to binary file from the object code

./powerpc-eabi-objcopy -O binary /home/yourusername/objectcode.o /home/yourusername/asm.bin

4. Print the assembled Hex byte code

cd /home/yousername
xxd -p -c 4 -u asm.bin

The assembled instructions (one word per line) are shown. If desired, you can instead open up the asm.bin file in a Hex Editor to view the assembled instructions.

NOTE about assembling source with branch labels:

View the following source~


Code:
b label
li r3, 0
label:
stw r3, 0x8 (sp)


There's nothing wrong with the above source, but let's pretend you forgot to add "label:" (the landing spot for 'b label'), and your source now looks like this...


Code:
b label
li r3, 0
stw r3, 0x8 (sp)


Even though you are missing the branch's landing spot, this will still assemble on DevkitPPC (powerpc-eabi-as). Powerpc-eabi-as will apply a branch value of zero (a branch that just branches to itself) to any branches that are not equipped with a landing spot. This is important to remember as any branch instruction with a jump of zero will 'crash' your game. I'm not sure if there's an option on the powerpc-eabi-as to disable this 'nuisance'. This 'nuisance' can actually be handy if you are needing to prematurely test out a huge ASM source and haven't yet finished/completed all the branches.




TO DISASSEMBLE ASSEMBLY (from binary file)

1. Navigate to binutils

cd /opt/devkitpro/devkitPPC/bin

2. Disassemble the binary file, display results on terminal screen

./powerpc-eabi-objdump -b binary -m powerpc:750 -M broadway -D -EB /home/yourusername/asm.bin

The source will be displayed on the screen. Please note branch instructions will NOT have normal hex-offset values. The values in the branch instructions are for the addresses within the binary file itself. (Example: b 0x14 = branch to address 0x00000014 of the binary file)



INCLUDE MULTIPLE FILES TRICK

If your file is extremely large, you can break it into multiple files, for easy use of subroutine/function calls.

Example: You have a function call named "init_start" in your example.s file, but you want the function to be in its own file. Create another file called subroutine.s and cut and paste all the contents of the init_start function call from example.s to subroutine.s. Still keep the instruction of "bl init_start" in your example.s file.

At the very top above everything you pasted in, place this in subroutine.s--

Code:
init_start:

Save and close the file and open example.s. Now where ever you want the subroutine code contents to be placed at after compilation, place the following...

Code:
.include "/path/to/the/subroutine.s"

Replace /path/to/the with the actual directory path to subroutine.s. This will allow example.s to link together the subroutine.s file. Save and close the file. Now just assemble the example.s in a normal fashion.



Final NOTES:
You could always place all your .include links at the top of your file, but have the first instruction in your main file (example.s) simply be a branch to jump all the them at the very start of the execution of your ASM, like this...

Code:
b start_asm
.include "/path/to/the/subroutine.s"
.include "/path/to/the/subroutine2.s"
.include "/path/to/the/subroutine3.s"
.include "/path/to/the/subroutine4.s"
start_asm:
...

Please note that older versions of devkit's binutils and possible future versions may not work with this guide.

Versions of executables used in this guide:
GNU Binutils Version 2.30
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)