kategoria: ANSI C
[#1] asm to c
Jak ma wyglądać program w C z poniższego fragmentu w asm.

Deklaracja struktury
STRUCTURE cvt,0
...
APTR cvt_fbuf1 ;wskaźnik do tablicy wskaźników, które wskazują na bajty danych
APTR cvt_fbuf2 ;tu podobnie

;a3 zawiera wskaźnik na strukturę cvt
;chcę pobrać adres w poniższy sposób
moveq #1,d0 ;przykładowy nr tablicy
moveq #0,d1 ;przykładowy nr 0 lub 1
;pobieram adres z fbuf1 lub fbuf2
move.l cvt_fbuf1(a3,d1.w*4),a6
;pobieram adres z tablicy wskaźników
move.l 12(a6,d0.w*4),a6

Jak to napisać w C?

struct cvt {
...
UBYTE **FBuf1, **FBuf2;
}

UBYTE *lbuf, **buf;
UWORD nr1, nr2;

nr1=0;
nr2=1;

buf = cvt->FBuf1[nr1];
lbuf = buf[nr2+3];

Co jest źle?
[#2] Re: asm to c

@cholok, post #1

Na początek nie widzę gdzie jest stworzona instancja struktury cvt. Żeby się do niej odwoływać trzeba stworzyć obiekt - instancje - struktury np.: cvt cvt_instance;
I teraz jak to jest normalny obiekt, to odwołujemy się do pól poprzez kropkę (.) a nie strzałkę (->). Strzałką odwołujemy się do pól struktry, jeżeli mamy wskaźnik na instancję struktury np.:
cvt* cvt_wsk = &cvt_instance;
buf = cvt_wsk->FBuf1;

a normalnej instacji;
buf = cvt_instance.FBuf1.
[#3] Re: asm to c

@flops, post #2

To jest tylko fragment.
Deklaracja jest.
struct cvt *cvt;

Chodzi o to, że wyskakują błędy typu mismatch pointer.
jak dam nr1=0 to
buf = cvt->FBuf1[nr1]; ma być tak jakbym dał buf = cvt->FBuf1
a jak dam nr1=1 to ma być buf = cvt->FBuf2
ale coś nie pasuje.
[#4] Re: asm to c

@cholok, post #3

W C to tak nie zadziała. Trzeba zamienić troszkę strukturę struktury. Za raz pomyślę, jak mi starczy czasu to odpiszę dzisiaj, jak nie to jutro.
[#5] Re: asm to c

@cholok, post #1

// deklaracja typu struktury
typedef struct {
...
UBYTE **FBuf1, **FBuf2;
} tCvt;

// deklaracja zmiennej strukturalnej
tCvt cvt;
// reszta deklaracji
UBYTE wartosc, *lbuf, **buf;
UWORD nr1, nr2;
nr1=0;
nr2=1;

// niech buf posiada adres tablicy
buf = cvt.FBuf1; // (zmienna typu UBYTE**) podstaw (wartość typu UBYTE**)
// niech lbuf posiada adres (nr2+3)-tego wiersza
lbuf = buf[nr2+3]; // (zmienna typu UBYTE*) podstaw (element UBYTE** czyli wartość UBYTE*)


Możesz też spojrzeć na UBYTE ** jak na tablicę dwuwymiarową. Chcąc dorwać adres n-tego wiersza możesz zrobić: ptr = cvt.FBuf1[n], ale możesz też od razu wleźć do danej komórki (n,m): b = cvt.FBuf1[n][m]

Piszesz dekompiler? ;)

@flops: w C nie ma obiektów. ;)

Ostatnia aktualizacja: 23.07.2015 17:43:08 przez teh_KaiN
[#6] Re: asm to c

@teh_KaiN, post #5

Tablica jest jednowymiarowa.
fbuf1 i fbuf2 w strukturze to wskaźniki na tablice kolejnych wskaźników. Jako, że fbuf1 i fbuf2 są kolejno po sobie to traktuję fbuf1 jako 2-elementową i jednowymiarową tablicę. Z pierwszej tablicy chcę pobrać wskaźnik na jedną z dwóch tablic, zaś z tablicy n-ty wskaźnik na bufor danych. Popatrz na przytoczony kod w asmie.

Piszę converter.

Ostatnia aktualizacja: 23.07.2015 17:54:21 przez cholok
[#7] Re: asm to c

@cholok, post #6

Ja nieasmowy. ;)

Z tymi wymiarami tablic zależy jak patrzeć. Pojedynczy wskaźnik jest prawie że tożsamy z tablicą jednowymiarową na typ prosty, podwójny wskaźnik można interpretować albo jako tablicę tablic (dwa wymiary) albo tablicę wskaźników. W Twoim przypadku będzie to mniej więcej coś takiego:

// typ
typedef struct {
// 1D tablice wskaźników
UBYTE** pBuf1;
UBYTE** pBuf2;
} tBufory;
// zmienna strukturalna
tBufory sBufory;
UBYTE** pTablicaBuforow;
UBYTE *pBuf; // pojedynczy bufor

pTablicaBuforow = sBufory.pBuf1; // lub "= sBufory.pBuf2"
pBuf = pTablicaBuforow[n];


Jeśli chcesz się odwoływać za pomocą offsetu do pBuf1 lub pBuf2 to możesz to załatwić tak:

pTablicaBuforow = ((UBYTE ***)(&sBufory.pBuf1))[bOffs];
gdzie bOffs = 0 dla pBuf1 lub 1 dla pBuf2. Zapis w innej konwencji:

pTablicaBuforow = *((UBYTE***)(&sBufory.pBuf1) + 1);
[#8] Re: asm to c

@teh_KaiN, post #7

Ja nieceowy.szeroki uśmiech

Twój przykład zbyt skomplikowany.
Wystarczyło buf = &cvt->FBuf1[nr1];
[#9] Re: asm to c

@cholok, post #8

A nie dostaniesz się wtedy do elementu "nr1" tablicy FBuf1 zamiast adresu FBuf2?

"&cvt" - adres cvt, "->" wyłuskanie spod adresu, czyli zapis skraca się do "cvt.FBuf1[nr1]". Chyba że czegoś nie uwzględniam. ;)

Świetna inicjatywa z tym konwerterem. Jak zamierzasz rozwiązać zagadnienie samo modyfikującego się kodu?
[#10] Re: asm to c

@teh_KaiN, post #9

Już nie kombinuję, bo działa dobrze.

Świetna inicjatywa z tym konwerterem.


Czemu świetna?

Jak zamierzasz rozwiązać zagadnienie samo modyfikującego się kodu?


Nie zamierzam, bo takiego nie ma.
[#11] Re: asm to c

@cholok, post #10

Bo jeśli kiedykolwiek to udostępnisz to bym mógł sobie popatrzeć jak pewne konstrukty asma 68k tłumaczą się na konstrukty C, co pozwoliłoby mi na szybkie nauczenie się tego języka. Poza tym, mając translator asm -> C wystarczy dodać translator języka maszynowego na dany dialekt asm i dekompilator gotowy. Oczywiście zadanie nie byłoby proste, ale można by się w to pobawić. Każdą grę by można było przystosować pod nowy hw albo chociaż odpalanie z dysku twardego bez potrzeby używania whdload.

A samo modyfikujący się kod istnieje. Z tego co mi wiadomo, to można się na to naciąć w niektórych starych produkcjach amigowych (nie wiem jakich) oraz jest to praktyka nie polecana, bo byle procesor z cache'em pracuje z takim czymś wolniej, o ile się nie posypie.

Drugi akapit nie należy traktować jako opinia jakiegoś pr0 kodera, bo taki mastah nie jestem, są to informacje zasłyszane i wyczytane w zakątkach internetu.

Ostatnia aktualizacja: 23.07.2015 22:21:28 przez teh_KaiN
[#12] Re: asm to c

@teh_KaiN, post #11

Aaa, nie zrozumieliśmy się. Piszę konwerter obrazu, nie języka.
[#13] Re: asm to c

@teh_KaiN, post #5

Obiekt w sensie instancja struktury, napisałem żeby było łatwiej zrozumieć. Bo słowo instancja nie jest takie oczywiste dla kogoś kto ma pierwszy raz styczność z C
Co to obiektów z C++, czy innego języka do OOP (Object-oriented programming), jak java, C# itd., to w C można również programować obiektowo z użyciem polimorfizmu, ale trzeba używać zaawansowanych wskaźników na funkcje, co nie jest takie przejrzyste jak w językach obiektowych.

Co do samo-modyfikującego się kodu, to bardzo złe rozwiązanie. Tak się nie programuje od lat '80. W C musiałbyś i tak dodawać kod w ASM, żeby używać komend do zrzucania zawartości cache, bo nie ma automatycznego mechanizmu walidacji kodu z cache instrukcji do pamięci i aplikacja będzie się zawieszać po ponownym zaczytaniu z pamięci. W C pisze się już inaczej niż w ASM, bo jak chce się pisać tak samo, to powstają potworki strasznie trudne do analizy i całe dobrodziejstwo C znika. Lepiej już od razu pisać w ASM.

Ostatnia aktualizacja: 24.07.2015 10:21:58 przez flops
[#14] Re: asm to c

@cholok, post #8

Jednak nie działa. Po deasemblacji mamy:
buf = &(cvt->FBuf1[field]);

MOVE.L D5,D0 ;2005
ASL.L #$2,D0 ;e580
MOVE.L $28(A5),A0 ;206d 0028
ADD.L D0,A0 ;d1c0

Ta ostatnia instrukcja jest nadmiarowa. Reszta pasuje.
[#15] Re: asm to c

@cholok, post #14

Jest całkiem źle:
MOVE.L D5,D0
ASL.L #$2,D0
MOVE.L $28(A5),A0
ADD.L D0,A0

a powinno być:
MOVE.L D5,D0
ASL.L #$2,D0
MOVE.L $28(A5,D0.l),A0
[#16] Re: asm to c

@cholok, post #15

#include <stdio.h>
#include <stdlib.h>

struct cvt
{
unsigned char **FBuf1, **FBuf2;
} cvt;

int main(void)
{
int nr1 = 1;
int nr2 = 1;

unsigned char *arr1[] = {(void*)0xff, (void*)0xee};
unsigned char *arr2[] = {(void*)0xdd, (void*)0xcc};

cvt.FBuf1 = arr1;
cvt.FBuf2 = arr2;

printf("0x%x\n", (*(&cvt.FBuf1 + nr1))[nr2]);

return 0;
}


o takie cos ci chodzi?
[#17] Re: asm to c

@kiero, post #16

To by było coś takiego:
buf = *(&cvt->FBuf1 + nr1);
MOVE.L $28(A5,D5.L*4),A0 ;2075 5c28

Dzięki.
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