[#1] vbcc inline assembler
Tworzę funkcję assemblera w vbcc. Z grubsza wygląda tak:
void foo(__reg("a0") short *, __reg("a1") short *, __reg("a2") short *, __reg("d0") int) =
"    load (a0), e0\n"
....
"TheLoop:\n"
...
"    bne TheLoop\n";


Problem w tym iż VBCC nie jest na tyle inteligentny by zmienić nazwę etykiety TheLoop gdy kilkukrotnie używam funkcji foo. VASM Zgłasza iż "label TheLoop is redefined". Dokumentacja VBCC mówi by użyć offsetów - trochę nie wiem jak (lub skąd wziąć rozmiary opcodów m68k, AMMX mam). Z innych rzeczy zauważyłem iż vasm ma dyrektywe inline/einline więc spróbowałem:
void foo(__reg("a0") short *, __reg("a1") short *, __reg("a2") short *, __reg("d0") int) =
"    inline\n"
"    load (a0), e0\n"
....
"TheLoop:\n"
...
"    bne TheLoop\n";
"    einline\n"

jednak bez rezultatu. Jak rozwiązać ten problem?
[#2] Re: vbcc inline assembler

@fedaykin, post #1

Wiem, że w makrach asemblera stosuje się symbol \@ by odróżnić etykiety. Nie jestem jednak pewien, czy nada się to w tym przypadku.

Druga uwaga, to taka, że funkcja nie powinna być inline, bo ta dyrektywa kopiuje treść funkcji do każdego miejsca w programie gdzie jest używana. W przypadku, gdy etykieta ma być unikalna, powinna występować dokładnie raz w programie. Czyli być oddzielną podprocedurą, którą się wywołuje instrukcją skoku.
[#3] Re: vbcc inline assembler

@fedaykin, post #1

Użyj starożytnej techniki gdy jeszcze nie było lokalnych zmiennych. Tu przykładzik.

btst	#6,$bfe001
		bne.b	*-8
		rts

W tym przykładziku to tak jakbyś napisał coś takiego
start:	btst	#6,$bfe001
	 	bne.b	start
		rts


Kolejny przykładzik tylko że z wartością dodatnią
btst	#6,$bfe001
	bne.b	*+8
	nop
	nop
	nop
	rts

To tak jakbyś napisał coś takiego
btst	#6,$bfe001
	bne.b	tu
	nop
	nop
	nop
tu	rts


rozmiary opcodów najlepiej się nauczyć deasemblując choćby Twój kod inline na przykład w Asm-One. Ogólnie opcody mają parzystą liczbę bajtów i najmniej ich jest dwa ( na przykład nop, rts) a najwięcej to bodajże 10 ( move.l adres1,adres2 ).

W powyższych przykładzikach opcody mają następujące rozmiary:
btst #6,$bfe001 - 8 bajtów (instrukcja dwa bajty, dwa bajty na wartość po # i cztery na adres)
bne.b *-8 - 2 bajty
bne.b *+8 - 2 bajty
rts - 2 bajty
nop - 2 bajty

Sztuczka rozwiązująca problem w niektórych przypadkach.
Możesz też użyć zmiennych lokalnych w foo ale wtedy możesz raz używać foo w obrębie danej funkcji (sprawdziłem to).

Sprawdziłem i nie można używać labeli z makr typu: zmienna\@.

I sztuczka rozwiązująca problem bez znajomości rozmiarów opcodów, lecz wtedy sypnie warningami o nieużywanych labelach. lokalne labele w inline + labele w kodzie C.
void foo() =
".TheLoop:\n"
"\t nop\n"
"\t bne .TheLoop\n"
"\t rts";

void tes()
{
	foo();
}

int main()
{
	foo();
label1:
	foo();
	return 0;
}
[#4] Re: vbcc inline assembler

@asman, post #3

Ogólnie opcody mają parzystą liczbę bajtów i najmniej ich jest dwa ( na przykład nop, rts) a najwięcej to bodajże 10 ( move.l adres1,adres2 ).


Maksymalnie Opkody moga miec do 22 bajtow (pod 68020+):

move.l ([0xdeadbeef, A0, D0.w*2], 0xcafebabe),([0x123456, A1], D3.w*4, 0x987654)


Kwestii sensownosci powyzszego kodu nie dyskutujmy :)
[#5] Re: vbcc inline assembler

@mschulz, post #4

Dzięki za sprostowanie :)
[#6] Re: vbcc inline assembler

@asman, post #5

Eh, serio, nie wiecie o lokalnych etykietach? VBCC nie wspiera .Etykieta?

[...]


Aaaaaa, nawet w kontekscie funkcji .Etykieta bedzie wielokrotnie moja wina. Zaraz cos wiecej napisze;)

Ostatnia aktualizacja: 26.04.2019 20:26:18 przez kiero
[#7] Re: vbcc inline assembler

@kiero, post #6

Od razu mowie, nie sprawdzane. Ale moze by po prostu wrzucic takie cos na poczatek kazdej rutynki w ASM:

"__FUNC__##_LINE__:"

Ogolnie po to zeby wstawic punkt startowy dla kazdej podetykiety. Nie mam pojecia czy preprocessor dziala na wstawki w asmie ale powinien?
[#8] Re: vbcc inline assembler

@kiero, post #6

I w tym tkwił szkopuł (i w tym iż ja dziergam głównie w C a do assemblera to ostatnio po latach wracam). Etykieta powinna być lokalna. Wraz z dyrektywą/blokiem vasm inline/einline (która określa blok unikalnych lokalnych etykiet) poprawna wersja wygląda tak:
void foo(__reg("a0") short *, __reg("a1") short *, __reg("a2") short *, __reg("d0") int) =
"    inline\n"
"    load (a0), e0\n"
....
".TheLoop:\n"
...
"    bne .TheLoop\n";
"    einline\n"

Kompiluje się żadnych warningów! :) Dzięki Wszystkim!
[#9] Re: vbcc inline assembler

@asman, post #3

Próbowałem jak w twoim poście, jednak po drodze znalazłem jednak rozwiązanie z lokalnymi etykietami. U mnie disassembler trochę szalał bo nie znał nowych rozkazów z vampirka. AsmOne nie próbowałem choć jak przyjdzie mi kiedyś to spróbuję.
[#10] Re: vbcc inline assembler

@Hexmage960, post #2

W sumie dla tej funkcji mi obojętnie czy ją kompilator zinline-uje czy nie. Ta funkcja to jest mnożenie macierz 3x3 przez wektor, tylko że dla całej tablicy wektorów (żeby tylko raz wgrać macierz do rejestrów i przejechać w ciasnej pętli po wszystkim). Więc liczba wywolań do ilości danych jest mała. Przy czym w vbcc funkcje assemblera są zawsze inlineowane. Mógłbym opakować to w inną funkcję C, jednak vbcc też może sobie ją zinlineować :) Wyłączyć mogę tylko globalnie inlineowanie - a to może pogorszyć prędkość w innych miejscach gdzie mam małe funkcyjne pchełki.
[#11] Re: vbcc inline assembler

@fedaykin, post #9

No to gitara, że znalazłeś rozwiązanie.

Jeśli chodzi o vampira to bodajże najnowszy AsmPro ma jakieś tam wsparcie to i może deasemblacja takiego kodu będzie znośna.
Na stronie www.PPA.pl, podobnie jak na wielu innych stronach internetowych, wykorzystywane są tzw. cookies (ciasteczka). Służą ona m.in. do tego, aby zalogować się na swoje konto, czy brać udział w ankietach. Ze względu na nowe regulacje prawne jesteśmy zobowiązani do poinformowania Cię o tym w wyraźniejszy niż dotychczas sposób. Dalsze korzystanie z naszej strony bez zmiany ustawień przeglądarki internetowej będzie oznaczać, że zgadzasz się na ich wykorzystywanie.
OK, rozumiem