Zgrywus

    -- Sebastian Pawlak, PCKurier 26/1995.


Niektórzy pewnie pamiętają z pism poświęconych ośmiobitowym komputerom zamieszczane tam programy. Były to niekiedy wielostronnicowe szeregi cyfr w systemie heksadecymalnych, które po zmodyfikowaniu specjalnym programem tworzyły np. grę czy program użytkowy. System szesnastkowego zapisu programu jest bardzo wygodny, gdyż pozwala niewielkim nakładem sił wpisać wielokrotnie wiekszy program. Na przykład zamieszczony na wydruku 1 program w asemblerze zajmuje 497 bajtów, a w zapisie heksadecymalnym 211.

Zasady asemblacji są następujące:

Tasm Wersja.asm

Tlink /t Wersja.obj

Ten sam program w zapisie szesnastkowym maszynowej wersji programu z wydruku 1 ma postać.

eb,1a,90,b4,09,cd,21,c3,57,65,72,73,6a,61,20

44,4f,53,20,24,2e,24,20,24,20,0d,0a,24,ba,08

01,e8,e1,ff,b4,30,cd,21,04,30,80,c4,30,a2,16

01,88,26,18,01,ba,16,01,e8,cb,ff,ba,14,01,e8

c5,ff,ba,18,01,e8,bf,ff,b4,4c,cd,21



Jak działa Zgrywus? Dwa programy przedstawione na wydrukach 2 i 3 to: char2hex, przetwarzający pliki na pliki z rozszerzeniem.Com w zapisie heksadecymalnym i hex2char, odwracający sytuację.

Obowiązują nastepujące zasady postępowania:

Program, np. w Assemblerze, przetwarzamy na maszynowy (czyli kompilujemy).
Otrzymany plik com lub exe wstawiamy jako parametr, Char2hex.exe plik.com plik.hex.
Otrzymany plik "plik.hex" drukujemy w naszej gazecie.
Użytkownik, który kupił czasopismo, przepisuje program do pliku.
Następnie uruchamia program Hex2char.exe, w taki sposób: Hex2char.exe plik.hex plik.com, co powoduje zapisanie do pliku "plik.com" przekształconego już programu.
Czytelnik zauważy jeszcze na ekranie sumę kontrolną pliku z gazety i tę, która została obliczona w jego wersji pliku. Jeśli sumy różnią się, to znaczy, że użytkownik popełnił błąd w przepisywaniu.

Przewidując pytania, jakie mogą mieć czytelnicy, z góry udzielę na nie odpowiedzi.

Przecież można jeszcze bardziej zmniejszyć program, publikując wydruk pliku w formacie.com?
Można tak zrobić, ale wpisywanie programu w bajtach jest dosyć uciążliwe, dlatego stosuje sie wydruki szesnastkowe mniejsze niż program w danym języku, ale łatwiejsze do wpisania niż kod maszynowy.

Przecież publikowanie programów źródłowych nie jest stosowane dla zabawy, ale w celu nauczenia kogoś zasady działania opublikowanego programu?
Tak właśnie jest. W przypadku programów w języku wysokiego poziomu poddaję się (można je tylko uruchamiać), ale jeśli program jest w Assemblerze, to od czego są debuggery? Co prawda program napisany w Pascalu też można oglądać pod debuggerem, ale wtedy bęzie to już kod w asemblerze, a nie program pascalowy.


Wydruk 1

Main SEGMENT
Assume Cs:Main,Ds:Main
Org 100h
Begin:
 jmp Start
 Write PROC Near
  mov ah,9h
  int 21h
 RET
 Write ENDP
	
 Tekst DB 'Wersja DOS ','$'
 Kropa DB '.','$'
 Wer_g DB ' ','$'
 Wer_p DB ' ',13,10,'$'
	    
Start:
 mov dx,Offset Tekst
 call Write
 mov ah,30h
 int 21h
 add al,48
 add ah,48
 mov Wer_g,al
 mov Wer_p,ah
    
 mov dx,Offset Wer_g
 call Write
 mov dx,Offset Kropa
 call Write
 mov dx,Offset Wer_p
 call Write
			  
 mov ah,4ch
 int 21h
Main ENDS
END Begin



Wydruk 2 - char2hex

{ Char2Hex wer.1.0  Sebastian Pawlak  1994r.}
Program _char2hex_;
Uses dos,crt;
Var Odczyt,Zapis   :text;
    Bajt           :char;
    Pozycja_w_pliku:word;
    Opis_pliku     :searchrec;
    Kontrola       :longint; {Suma kontrolna pliku}
Const Szer=15; {ilość liczb w kolumnie}

Function Char2hex (Znak:char) :string; {dec na hex}
Var L     :array  [0..1] of byte;
    Hex   :string [2];
    Petla       :byte;
Begin
 Hex:='--';
 L [0]:=ord (Znak) div 16*16;
 L [1]:=ord (Znak)-L [0];
 L [0]:=L [0] div 16;
 For Petla:=0 to 1 do
 Begin
  Hex [Petla+1]:=chr(L [Petla]+48);
  If L [Petla]>9 then Hex [Petla+1]:=chr(L [Petla]+97-10);
 End;
 Char2hex:=Hex;
End;

Begin
 If paramcount<2 then
    writeln ('Skladnia: Char2Hex.exe zrodlo.chr cel.hex')
 Else
 Begin
  findfirst (paramstr (1),Archive,Opis_pliku);
  If Opis_pliku.Name='' then
  Begin
   write ('Brak pliku.'); halt;
  End;
  assign (Odczyt,paramstr (1));
  assign (Zapis ,paramstr (2));
  reset   (Odczyt);
  rewrite (Zapis);
  writeln (Zapis,'Char2Hex wer.1.0 Sebastian Pawlak');
  Pozycja_w_pliku:=0;
  Kontrola:=0;
  Repeat
   read (Odczyt,Bajt);
   Pozycja_w_pliku:=Pozycja_w_pliku+1;
   Kontrola:=Kontrola+ord (Bajt)*Pozycja_w_pliku;
   If ((Pozycja_w_pliku div Szer=Pozycja_w_pliku/Szer)or
      (Pozycja_w_pliku=Opis_pliku.Size)) then
       writeln (Zapis,char2hex (Bajt))
   Else write (Zapis,char2hex (Bajt),',');
   gotoxy (1,wherey);
   write(round(Pozycja_w_pliku/Opis_pliku.Size*100),'%');
  Until Pozycja_w_pliku=Opis_pliku.Size;
  writeln (Zapis,'*',Kontrola);
  close (Odczyt); close (Zapis);
 End;
End.



Wykres 3 - hex2char

{ Hex2char wer.1.0  Sebastian Pawlak  1994r.}
Program _Hex2char_;
Uses dos,crt;
Var Odczyt,Zapis      :text;
    Hex               :string [3];
    Opis_pliku        :searchrec;
    Czolowka,Wiersz   :string;
    Petla,Dec         :byte;
    Pozycja_w_wierszu :byte;
    Pozycja_w_danych  :word;
    Kod               :integer;
    Kontrola          :longint;
Begin
 If paramcount<2 then
    writeln ('Skladnia: Hex2Char.exe zrodlo.hex cel.chr')
 Else
 Begin
  findfirst (paramstr (1),Archive,Opis_pliku);
  If Opis_pliku.Name='' then
  Begin
   write ('Brak pliku.'); halt;
  End;
  assign (Odczyt,paramstr (1));
  assign (Zapis ,paramstr (2));
  reset   (Odczyt);
  rewrite (Zapis);
  readln (Odczyt,Czolowka);
  Writeln ('Czolowka: ',Czolowka);
  Hex:='$--';
  Kontrola:=0;
  Pozycja_w_danych:=0;
  Repeat
   readln (Odczyt,Wiersz);
   If Wiersz [1]'*' then {koniec danych, poczatek sumy}
   Begin
    For Pozycja_w_wierszu:=0 to length (Wiersz) div 3 do
    Begin
     For Petla:=1 to 2 do
       Hex [Petla+1]:=Wiersz [Petla+Pozycja_w_wierszu*3];
     val (Hex,Dec,Kod);
     write (Zapis,chr (Dec));
     Pozycja_w_danych:=Pozycja_w_danych+1;
     Kontrola:=Kontrola+Dec*Pozycja_w_danych;
    End;
    write ('.');
   End;
  Until Wiersz [1]='*';
  writeln;
  writeln ('Suma kontrolna stara: ',Wiersz,'  nowa: *',
           Kontrola);
  close (Odczyt); close (Zapis);
 End;
End.
w3cw3c
automatyka przemysłowa