Recently, Tari on Cemetech posted a short piece about programming Assembly for C libraries. In order to generate libraries usable in C programs, a specific format must be used. First of all, the registers are each assigned the following uses by GCC:

- r0-r1 Stores function return value, caller saves.

- r2-r3 Scratch space, caller saves.

- r4-r7 Function parameters, caller saves.

- r8-r13 Scratch, callee saves.

- r14 Frame pointer, callee saves.

- r15 Stack pointer, callee saves.

- MACH,MACL Callee saves.

If an argument is more than 32 bits long, it's pushed onto the stack rather than split amongst different registers.

The format for a function in such a library is to declare the function global with the .global tag. An example of this would be this function to return the jump to a syscall:

`.global _Syscall`

/* Syscall(short <syscall number>) */

/* Jumps to the syscall */

mov.l Table,r2

shll2 r4

mov.l @(r4+r2),r0

jsr @r0

nop

nop

Table: .long 0x805EDCA8

The code is then included in the compiled code with the #include <example.s> declaration.

Using this, I've been working on a few libraries recently to help with some of GCC's weak areas and other speed critical functions.

Partial list of implemented and planned functions for my math library (which I've actually had around for quite some time):

Modulus

Arbitrary precision addition

Arbitrary precision subtraction

Arbitrary precision multiplication

Arbitrary precision integer division

Hardware division

64 bit operations

Single precision Floating point operations

OS variable floating point operations

Integer Square root

Integer inverse square root

Floating point -> integer conversion

Integer->Floating point conversion

Floating point Absolute value (it's like two lines, but whatever :p)