public _StrSize _StrSize MOVEA.L a0,a1 .1 TST.B (a0)+ BNE.S .1 SUBA.L a1,a0 MOVE.L a0,d0 RTS
ULONG StrSize(REG("a0") CONST UBYTE *s) { CONST UBYTE *p; p = s; while (*s++); return (s - p); }
_StrSize MOVE.L a0,d0 .1 TST.B (a0)+ BNE.S .1 SUBA.L d0,a0 MOVE.L a0,d0 RTS
_StrSize MOVEA.L a0,a1 MOVE.L a1,d1 MOVEA.L a1,a0 ADDQ.L #1,a1 TST.B (a0) BEQ.S .2 .1 MOVEA.L a1,a0 ADDQ.L #1,a1 TST.B (a0) BNE.S .1 .2 MOVE.L a1,d0 SUB.L d1,d0 RTS
@Krashan, post #1
ULONG StrSize(register __A0 UBYTE *s) { UBYTE *p = s; while (*s) s++; return(s - p); }
section text,code ds.l 0 procstart ds.w 0 xdef @StrSize @StrSize: movem.l l7,-(sp) link A5,#-l4 move.l A0,A1 bra l2 l1 addq.l #$01,A0 l2 tst.b (A0) bne l1 l3 move.l A0,D0 sub.l A1,D0 bra l5 l5 unlk A5 rts l7 reg l6 equ 8 l4 equ 0 procend END
@Krashan, post #1
_StrSize movem.l l11,-(a7) move.l (4+l13,a7),a1 move.l a1,a2 l8 l9 move.l a1,a0 addq.l #1,a1 tst.b (a0) bne l8 l10 move.l a1,d0 sub.l a2,d0 l6 l11 reg a2 movem.l (a7)+,a2 l13 equ 4 rts
@asman, post #3
; Maxon C++ Compiler ; Work:Test.c SECTION ":0",CODE XDEF _StrSize _StrSize L3 EQU 4 L4 EQU $400 move.l a2,-(a7) move.l a0,a2 L1 L2 tst.b (a0)+ bne.b L2 move.l a0,d0 sub.l a2,d0 move.l (a7)+,a2 rts XDEF _main _main L5 EQU 0 L6 EQU 0 moveq #0,d0 rts END
@Hexmage960, post #4
Wyszło niemal dokładnie jak GCC.No nie bardzo. Zauważ, że z jakiegoś powodu Maxon do przechowania początkowej wartości wskaźnika na string użył rejestru A2. Ponieważ funkcje mają obowiązek go przechować, to musiał go zrzucić na stos i potem przywrócić. Dwa dostępy do pamięci ekstra. Niby niewiele, ale przy intensywnym używaniu tej funkcji może już mieć znaczenie. Tym bardziej, że nie ma żadnego racjonalnego powodu, żeby nie użyć do przechowania wskaźnika rejestru A1, D0 czy D1.
@Krashan, post #5
; Maxon C++ Compiler ; Work:Test.c SECTION ":0",CODE XDEF _StrSize _StrSize L3 EQU 0 L4 EQU 0 move.l a0,a1 L1 L2 tst.b (a0)+ bne.b L2 move.l a0,d0 sub.l a1,d0 rts XDEF _main _main L5 EQU 0 L6 EQU 0 moveq #0,d0 rts END
@Hexmage960, post #6
#include <exec/types.h> ULONG StrSize(register __a2 UBYTE *s) { const UBYTE *p; p = s; while (*s++) ; return(s - p); } main() { return 0; }
; Maxon C++ Compiler ; Work:Test.c SECTION ":0",CODE XDEF _StrSize _StrSize L3 EQU 0 L4 EQU 0 move.l a2,a0 L1 L2 tst.b (a2)+ bne.b L2 move.l a2,d0 sub.l a0,d0 rts XDEF _main _main L5 EQU 0 L6 EQU 0 moveq #0,d0 rts END
@Hexmage960, post #7
@Krashan, post #1
@sanjyuubi, post #9
void MemCpy(register __a0 ULONG *s, register __a1 ULONG *d, register __a2 ULONG *e) { while (s < e) *d++ = *s++; }
XDEF _MemCpy _MemCpy L5 EQU 0 L6 EQU 0 bra.b L2 L1 move.l (a0)+,(a1)+ L2 cmp.l a2,a0 blt.b L1 rts
@Krashan, post #11
Kroskompilacja mnie nie interesuje.
@retronav, post #13
nie troluję, jestem ciekaw z racji małego stażu w kodowaniu na Ami...
@retronav, post #13
a uzasadnisz dlaczego?Piszę aktualnie rzeczy będące blisko sprzętu i obsługujące sprzęt podłączony do prawdziwej Amigi. Nie są to duże programy, więc kompilują się w miarę szybko nawet na mojej 68020 @ 28 MHz, a nie muszę się bawić w przenoszenie skompliowanego pliku za każdym razem. A poza tym lubię klimat pracy na prawdziwej A1200.
@sanjyuubi, post #9
#include <stdio.h> #include <exec/types.h> LONG MemCmp(UBYTE *s1, UBYTE *s2, ULONG size) { LONG diff=0; while (size > 0) { size--; if (diff = *s1++ - *s2++) break; } return(diff); } main() { static UBYTE tab[]={1, 2, 3, 4}, tab2[]={1, 2, 4, 3}; LONG wynik; wynik = MemCmp(tab, tab2, sizeof(tab)); printf("%ld\n", wynik); return 0; }
XDEF _MemCmp _MemCmp L7 EQU $14 L8 EQU $4CC movem.l d2/d3/d6/d7/a2,-(a7) move.l L7+$C(a7),d3 move.l L7+$8(a7),a0 move.l L7+4(a7),a2 moveq #0,d2 bra.b L2 L1 subq.l #1,d3 moveq #0,d7 move.b (a2)+,d7 moveq #0,d6 move.b (a0)+,d6 sub.l d6,d7 move.l d7,d2 bne.b L4 L2 cmp.l #0,d3 bhi.b L1 L4 move.l d2,d0 movem.l (a7)+,d2/d3/d6/d7/a2 rts