Konwerter surowych danych na asembler

0

Niedawno napisałem program, którego zadaniem jest konwersja dowolnego pliku na asembler - przykładowo piszemy grę rysując grafiki w edytorze graficznym, i potem dzięki takiemu konwerterowi możemy je dołączyć do naszej gry. Wstępnie go przetestowałem konwertując jego samego, potem asemblując z powrotem i uruchamiając (uruchomił się poprawnie). Chciałbym jednak zasięgnąć waszej opinii, czy nie można by jeszcze czegoś tam poprawić.

Kod źródłowy:

/* convasm - raw data to assembly,
   written by Jan Mleczko in 2022 */
#include <stdio.h>

#define bpline 19 /* bytes per line */

int main (int argc, char **argv)
{ FILE *ifp, *ofp;
  unsigned int i, length = 0;
  unsigned char line[bpline];
  if (argc < 3)
  { puts ("convasm - raw data to assembly");
    return 1;
  }
  ifp = fopen (argv[1], "rb");
  if (!ifp)
  { puts ("can't read input file!");
    return 1;
  }
  ofp = fopen (argv[2], "w");
  if (!ofp)
  { puts ("can't write output file!");
    return 1;
  }
  while (!feof (ifp))
  { getc (ifp);
    ++length;
  }
  --length; rewind (ifp);
  fprintf (ofp, "; file %s, %u bytes\n", argv[1], length);
  while (1)
  { length = fread (line, 1, bpline, ifp);
    if (!length)
      break;
    fprintf (ofp, "DB %d", *line);
    for (i = 1; i < length; ++i)
      fprintf (ofp, ",%d", line[i]);
    putc ('\n', ofp);
  }
  fclose (ifp); fclose (ofp);
  return 0;
}
1

Dziwnie te klamry stawiasz :>

Nie wygląda źle, mogłeś dopisać jakieś komunikaty jeśli np. pierwszy plik nie występuje, jakiś komunikat błędu.

Konwertujesz plik do byte array, identyczne działanie ma incbin "plik.jpg", ale to po prostu inny sposób zrobienia tego samego.

Możesz sobie ulepszyć konwerter o parser nagłówków plików, gdzie tak jak teraz będziesz sobie wczytywał plik binary, ale podzielisz go na sekcje, headery odzielnie i reszta pliku oddzielnie, gdzie potem łatwo w assembly sobie tą tablice będziesz mógł modyfikować i zmienić zawartość nagłówków.
Ewentualnie na końcu linii każdego elementu nagłówka lub nad dopisać komentarz dla czytelności.

Taki parser da ci to samo co masz teraz, ale dodatkowo będziesz mógł ręcznie zmodyfikować plik jeśli zajdzie taka potrzeba, na razie nie wiadomo jaki bajt do czego służy więc nie wiadomo co zmodyfikować.
Oczywiście do wszystkich plików tego parsera nagłówków nie zrobisz, bo każdy jest inny, ale wsparcie może być np. dla kilku lub jednego na początek.

1

Dziwnie te klamry stawiasz :>

Próbowałem różnych styli stawiania klamr i dla mnie osobiście ten się najwygodniej czyta.

Nie wygląda źle, mogłeś dopisać jakieś komunikaty jeśli np. pierwszy plik nie występuje, jakiś komunikat błędu.

To jest rzeczywiście dobry pomysł, uaktualniłem kod w pierwszym poście.

Możesz sobie ulepszyć konwerter o parser nagłówków plików

W sensie, że generowało by coś takiego?

DD 12 ;BITMAPCOREHEADER.bcSize - The number of bytes required by the structure.
DW 32 ;BITMAPCOREHEADER.bcWidth - The width of the bitmap, in pixels.
DW 32 ;BITMAPCOREHEADER.bcHeight - The height of the bitmap, in pixels.
DW 1 ;BITMAPCOREHEADER.bcPlanes - This value must be 1.
DW 8 ;BITMAPCOREHEADER.bcBitCount - The number of bits-per-pixel. This value must be 1, 4, 8, or 24.

To brzmi ciekawie, choć jednocześnie było by to dosyć skomplikowane ulepszenie. Można by rozważyć jakąś modularną architekturę z wtyczkami dla różnych formatów i ich wariantów, system obsługi błędów itd. Należało by się też zastanowić, czy użyć komentarzy (jak powyżej), czy może etykiet - etykiety zajmowałyby miejsce w tablicy nazw asemblera i musiały by mieć jakiś ID (bo może być kilka bitmap w obrębie jednego programu), lecz byłyby bardziej formalne.

Co do tego parsera, inną sprawą jest, czy taka ręczna edycja jest powszechnym przypadkiem. Jeśli nie, to pomysł nie ma sensu, bo powodowałby znaczny wzrost objętości wynikowego pliku z kodem asemblerowym.

2

jakiś podział na funkcje? np. parsowanie/walidacja inputu oraz faktyczna logika biznesowa

używanie nowych linii aby porozdzielać kod? lol.

czemu nazwa programu jest nadpisywalna? :o

#define bpl 19

jakaś bardziej opisowa nazwa? albo chociaż komentarz

czemu

{ FILE *ifp, *ofp;

zamiast

{ 
   FILE *ifp, *ofp;

chyba drugi zapis jest "standardem"

0
1a2b3c4d5e napisał(a):

jakiś podział na funkcje? np. parsowanie/walidacja inputu oraz faktyczna logika biznesowa

używanie nowych linii aby porozdzielać kod?

+1

--length; rewind (ifp);

Od miliona lat nie widziałem rewind() - tu skutek zbyt prostej struktury programu, np braku jakiejś formy buforowania itd ...
Moje odczucie: zaprojektowane za pomoca debugera 12h przed deadline

0

czemu nazwa programu jest nadpisywalna?

Widziałem to już w paru innych programach. Jak ktoś u siebie zmieni nazwę na taką, która bardziej mu odpowiada, to po co w komunikatach upierać się przy oryginalnej?

#define bpl 19
jakaś bardziej opisowa nazwa? albo chociaż komentarz

Rzeczywiście trafne.

Od miliona lat nie widziałem rewind() - tu skutek zbyt prostej struktury programu, np braku jakiejś formy buforowania

Rozwiązanie z wstępnym ładowaniem wszystkiego do bufora też by działało, lecz trzeba byłoby ograniczyć rozmiar danych. Chyba że by alokować dynamicznie, ale to by już w ogóle skomplikowało kod, operacja alokacji spowolniłaby działanie, trzeba by było pamiętać o dealokacji, obsłużyć błędy braku pamięci, dziesięć razy sprawdzić wszystko pod kątem wycieków... A tutaj jedna dodatkowa linijka. Szczególnie, że to nie jest właściwie podwójne czytanie pliku, a jedynie obliczenie jego długości - które można by nawet przyśpieszyć po prostu skacząc na koniec i sprawdzając pozycję w pliku, ale na cplusplus.com piszą:

Library implementations are allowed to not meaningfully support SEEK_END (therefore, code using it has no real standard portability).

1 użytkowników online, w tym zalogowanych: 0, gości: 1