Mamy tu jakiegoś eksperta od assemblera Z80? Chodzi mi o wstawki assemblerowe w sdcc. Funkcja, która ma skoczyć bezwarunkowo pod adres:
void run(char* address){
__asm
pop HL
jp (HL)
__endasm;
}
Kompiluje się prawidłowo, ale nie działa. Ktoś może mi wytłumaczyć dlaczego? Ja to rozumiem w następujący sposób:
-argument przy wywołaniu funkcji jest wrzucany na stos
-instrukcja "pop HL" ściąga argument ze stosu do rejestru HL
-"jp (HL)" skacze bezwarunkowo pod adres przechowywany w rejestrze HL.
program zachowuje się tak, jakby nic się nie wykonało.
#programowanie #naukaprogramowania #retrocomputing
ataxbras

@6502 Ale co ma się zadziać, skoro zwracasz void? Skoczyło i tyle.

6502

@ataxbras Nie widzę efektów skoku. Wywołuję funkcję z argumentem 0x0000, a program nie zaczyna się wykonywać od początku. Edit: i nie wywala się jak podam jakiś losowy adres.

MostlyRenegade

@6502 ale dlaczego skaczesz do 0x0000, a nie tam, gdzie program jest załadowany?

ataxbras

@6502 W asm pykałem ze 25 lat temu, więc specem już dawno nie jestem (demencja :D). Tym bardziej nie jestem specem od SDCC, choć z C mam podobnie długą historię.

Jednak z tego co udało mi się wyłapać z sieci (bo Twój wpis spowodował, że stałem się sentymentalny i zacząłem grzebać), to wstawki asm w sdcc nie akceptują parametrów innych, niż global. Stąd, powinieneś przepisać zmienną wejściową funkcji do jakiejś zmiennej globalnej.

Ponadto, asm zwraca zawsze (nie ma potrzeby return), ale ty wymuszasz void. Nie wiem, czy to ma jakiś wpływ, ale widziałem deklaracje z __naked, które wyglądały dla mnie bardziej sensownie.

6502

@MostlyRenegade 0x0000 to początek ROMu na mojej płytce i jednocześnie początek programu.

@ataxbras Na dobrą sprawę nie przekazuję nic bezpośrednio do assemblera tylko ściągam ze stosu i właśnie o takim sposobie czytałem. Z global też spróbuję tylko muszę doczytać jak to zdefiniować, bo wydaje mi się że próbowałem z typową zmienna globalna zadeklarowana poza mainem i to wywalało jakiś błąd as linkera.

beetroot

Nie jesteście normalni, wracajcie do piwnicy ;)

ataxbras

@beetroot Najpierw musielibyśmy z niej wyjść

inskpektor

@6502 pod debugerem sprawdź co tam się faktycznie dzieje

6502

@inskpektor Nie ma debuggera

6502

@ataxbras @MostlyRenegade @inskpektor

Problem częściowo rozwiązany - zerknąłem w pośredni kod asemblera generowany przez sdcc. Parametr nie jest przekazywany przez stos, tylko przez rejestr hl, więc samo "jp (HL)" załatwia sprawę. Nadal działa to tylko w przypadku przekazania wskaźnika na funkcję, przy 0x0000 się wiesza. Edit: jednak działa, problem jest chyba przy powtórnej inicjalizacji UARTa bez soft resetu

ataxbras

@6502 Właściwie, jakby tak pomyśleć, to zdjęcie ze stosu jest rzeczywiście zbędne, skoro w jp wołasz HL bezpośrednio. Nie wiem jak miałoby to psuć kompilację, ale widocznie psuło.

Gratulacje, że Ci działa!

Zaloguj się aby komentować