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.





