@prz, post #3
@mareq, post #1
@Krashan, post #5
@c64portal, post #6
@Krashan, post #7
Pierwsze to oddzielny plik z kodem w asmie skompilowany np. VASM-em i zlinkowany.
@Hexmage960, post #9
GCC używa bowiem własnego, minimalistycznego formatu.Ale Vasm obsługuje ten format, wystarczy mu podać opcję -Faout.
GCC gwarantuje w zasadzie najnowsze standardy.GCC 2.95.3 (a o takim mówimy, jeżeli chcemy kompilować na Amidze) raczej nie gwarantuje najnowszych standardów... Zwłaszcza jeżeli chodzi o C++.
@Hexmage960, post #9
O, to ciekawe. Nie wiedziałem że można załączać kod z VASMa.
void c2p_init (int chunkyx, int chunkyy, int scroffsy, int bplsize ){
register volatile const void* _d0 ASM("d0") = chunkyx;
register volatile const void* _d1 ASM("d1") = chunkyy;
register volatile const void* _d3 ASM("d3") = scroffsy;
register volatile const void* _d5 ASM("d5") = bplsize;
__asm volatile (
"movem.l %%d0-%%d7/%%a2-%%a6,-(%%sp)\n"
"move.w #0,%%d2\n"
"jsr c2p1x1_8_c5_040_init\n"
"movem.l (%%sp)+,%%d0-%%d7/%%a2-%%a6"
: "+rf"(_d0), "+rf"(_d1), "+rf"(_d3), "+rf"(_d5)
:
: "cc", "memory"
);
}: "+rf"(_d0), "+rf"(_d1), "+rf"(_d3), "+rf"(_d5);)
@mareq, post #1
@asman, post #13
@Krashan, post #15
@c64portal, post #12
miałem na myśli coś takiegoOsoba, która to napisała, nie do końca ogarniała o co chodzi i wyszedł mały potworek. Który zapewne działa, ale jest niepotrzebnie skomplikowany. Cała ta funkcja robi za interfejs między C/C++ a procedurą c2p1x1_8_c5_040_init, która jest zapewne napisana w asemblerze. Cztery argumenty tej procedury powinny się znaleźć w rejestrach d0, d1, d3 i d5, przy czym kod błędnie sugeruje, że na powrocie z funkcji te rejestry zawierają wartości, które mogą być później użyte. Co nie jest prawdą, bo funkcja nie zwraca żadnego wyniku.
__asm volatile ("<kod>" : <wyjścia> : <wejścia> : <modyfikowane_rzeczy>);void c2p_init (int chunkyx, int chunkyy, int scroffsy, int bplsize )
{
register int _d0 __asm("d0") = chunkyx;
register int _d1 __asm("d1") = chunkyy;
register int _d3 __asm("d3") = scroffsy;
register int _d5 __asm("d5") = bplsize;
__asm volatile (
"movem.l d0-d7/a2-a6,-(sp)\n"
"move.w #0,d2\n"
"jsr c2p1x1_8_c5_040_init\n"
"movem.l (sp)+,d0-d7/a2-a6"
:
: "d"(_d0), "d"(_d1), "d"(_d3), "d"(_d5)
: "cc", "memory"
);
}00000db4 <c2p_init(int, int, int, int)>: db4: 2f05 move.l d5,-(sp) db6: 2f03 move.l d3,-(sp) db8: 202f 000c move.l 12(sp),d0 dbc: 222f 0010 move.l 16(sp),d1 dc0: 262f 0014 move.l 20(sp),d3 dc4: 2a2f 0018 move.l 24(sp),d5 dc8: 48e7 ff3e movem.l d0-d7/a2-a6,-(sp) dcc: 343c 0000 move.w #0,d2 dd0: 4eb9 0000 0000 jsr c2p1x1_8_c5_040_init dd6: 4cdf 7cff movem.l (sp)+,d0-d7/a2-a6 dda: 261f move.l (sp)+,d3 ddc: 2a1f move.l (sp)+,d5 dde: 4e75 rts
00000c50 <c2p_init(int, int, int, int)>: c50: 2f05 move.l d5,-(sp) c52: 2f03 move.l d3,-(sp) c54: 2608 move.l a0,d3 c56: 2a09 move.l a1,d5 c58: 48e7 ff3e movem.l d0-d7/a2-a6,-(sp) c5c: 343c 0000 move.w #0,d2 c60: 4eb9 0000 0000 jsr c2p1x1_8_c5_040_init c66: 4cdf 7cff movem.l (sp)+,d0-d7/a2-a6 c6a: 261f move.l (sp)+,d3 c6c: 2a1f move.l (sp)+,d5 c6e: 4e75 rts
@mareq, post #16
Jeśli ta mała społeczność amigowa ma funkcjonować to warto płacić są soft.Tu na korzyść dynxa przemawia to, że SAS/C nie możesz już od dawna kupić od producenta, od czasu jak wyprzedał wszystkie fizyczne kopie. W tej sytuacji producent mógłby umożliwić zakup wersji elektronicznej (np. pobranie obrazów dyskietek) z zastrzeżeniem, że produkt nie ma już wsparcia technicznego, czy nawet zezwolić na bezpłatną legalną dystrybucję, ale tego nie zrobił.
@Krashan, post #17
@c64portal, post #19
_swap:
swap d0
rts_swap:
move.l 4(a7),d0
swap d0
rtsunsigned long swap( unsigned long );
GCC 2.95.3 (a o takim mówimy, jeżeli chcemy kompilować na Amidze) raczej nie gwarantuje najnowszych standardów... Zwłaszcza jeżeli chodzi o C++.
Odmiany C to na razie dla mnie czarna magia a C uczyłem się z książki do ANSI C. Jak się ma 50 lat na karku to nauka już tak łatwo nie przychodzi. szeroki uśmiech
@Hexmage960, post #20
Przykładowo jeżeli mam instrukcję, która zdecydowanie lepiej jest implementowana w asemblerze, to piszę funkcję w asemblerze w oddzielnym pliku.Ja tam wolę mieć dobry kompilator. Popatrz:
static inline ULONG swap(ULONG x)
{
return (x << 16) | (x >> 16);
}
ULONG swaptest(ULONG y)
{
return swap(y) + 3;
}
00000dc4 <swaptest(unsigned long)>:
dc4: 4840 swap d0
dc6: 5680 addq.l #3,d0
dc8: 4e75 rts@Krashan, post #21
#define EndianWord(x) ((x) << 8) | ((x) >> 8)
#define EndianLong(x) ((EndianWord((UWORD)x)) << 16) | (EndianWord(x >> 16))
EndianLong:
ror.w #8,d0
swap d0
ror.w #8,d0
rts