In gcc you can write inline assembly or compose an assembly file, both ways works the same really.
Inline assembly:
+ fully interlockable with C
- more verbose
- you NEED to know the use of the key words “__asm volatile” and “__asm”
- you need to use implicit params (%), and how they work ("=>a", "=d", ...)
*+ it can be inlined, if performance heavily depends on inlining, that's the way to go
Assembly file:
+ more simple
- Intimidating at the start, since you have to learn a “new language”
+ you can use lifesaving macros
+ There are some parameters to avoid using % on registers and make it more like other assemblers
+ you can use maths on static data (another param to make it like C)
And now a very easy example, doing a byte copy, needed to copy data to the z80 ram; the idea is exactly the same:
Inline assembly:
Code: Select all
void memcpy8( void* destination, void const* source, u32 size )
{
u32 altSize;
u32 jmpSize;
// Copy blocks of 16bytes and less
altSize = size >> 4;
// jmpSize mean: ( full jump(16 instructions+remaing one) - (size/4)%16 ) * (size of instruction:2)
jmpSize = -((size << 1) & (0xF << 1));
__asm volatile (
" jmp (2f,%%pc,%3)\n"
"1: move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
" move.b (%0)+,(%1)+;"
"2: dbra %2, 1b\n"
: "=>a" (source), "=>a" (destination), "=d" (altSize)
: "d" (jmpSize), "0" (source), "1" (destination), "2" (altSize) );
}
Assembly file:
Code: Select all
*************************************************************
* void* memcpy8( void* const destination, void const* const source, u32 size )
* Needed to copy to z80 memory
*------------------------------------------------------------
* 4(sp) destination.l
* 8(sp) source.l
* 12(sp) size.l
*------------------------------------------------------------
* memcpy8ASM
*------------------------------------------------------------
* a1 destination.l
* a0 source.l
* d0 size.l
*************************************************************
ROUTINE memcpy8
movem.l 4(sp), d0/a0-a1
exg d0, a1
ROUTINE memcpy8ASM
* Backwards jump (d1)
moveq.l #(1 << 4) - 1, d1 /* And 15, because of unroll */
and.l d0, d1
lsl.l #1, d1 /* Mul by 2, because instruction size */
neg.l d1
* Number of loops (d0)
lsr.l #4, d0 /* Div by 16, because of unroll */
jmp 2f(d1.l, pc)
3: .rept 1 << 4
move.b (a0)+, (a1)+
.endr
2: dbra.w d0, 3b
move.l 4(sp), d0 /* return original destination */
rts
Edit: * added
HELP. Spanish TVs are brain washing people to be hostile to me.