; Copyright (C) 2006-2008 Bogdan 'bogdro' Drozdowski ; (bogdandr AT op.pl, bogdro AT rudy.mif.pg.gda.pl) ; ; Ostatnia modyfikacja kodu / Code last modified : 2008-08-23 ; ; Licencja / Licence: BSD ; http://www.opensource.org/licenses/bsd-license.php ; ; Mozna uzywac tego kodu w programach komercyjnych i niekomercyjnych, ; dopoki sa spelnione warunki licencji BSD. ; ; You are free to use the code here in commercial and non-commercial ; software, as long as the conditions of the BSD licence are met. ; Makro generujace liczby ciagu Fibonacciego w czasie kompilacji ; ; A macro which generates Fibonacci sequence numbers at assembly time ; ; Autor: Bogdan 'bogdro' Drozdowski macro fibon oper*, dst1, dst2, n* { if n = 1 | n = 2 H = 1 else if n > 0 F = 1 G = 1 H = F + G if n > 3 repeat n-3 F = G G = H H = F + G end repeat end if else H = 0 end if if dst1 eq & dst2 eq oper H else if dst2 eq oper dst1, H else oper dst1, dst2, H end if } ; sposob uzycia: ; use as follows: fibon db,,, -1 fibon db,,, 1 fibon db,,, 2 fibon db,,, 3 fibon db,,, 4 fibon db,,, 5 fibon db,,, 6 fibon db,,, 7 fibon mov, ax,, 5 fibon shld, edx, eax, 6 ; Makro generujace sume kontrolna ciagu bajtow od podanej etykiety ; w taki sposob, ze dodaje slowo o takiej wartosci, ze suma ; bajtow od tej etykiety do biezacej pozycji wraz z tym slowem wynosi zero ; ; A macro which generates a checksum of bytes beginning at the specified label ; in such a manner, that it declares a word such that the sum of bytes ; beginning at the label including this declared word is zero. ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro chksum etyk* { suma = 0 repeat $ - etyk load X byte from etyk + % - 1 suma = suma + X end repeat dw -suma } ; sposob uzycia: ; use as follows: xxx: db 1, 2, 3, 4, 5 chksum xxx ; Makro generujace 16-bitowy daleki CALL ("push cs, push ip") do ; podanej etykiety 'nazwa' ; ; A macro which generates a 16-bit far CALL ("push cs, push ip") ; to the specified label 'nazwa' ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro skacz nazwa* { local __1_adres mov word [cs:__1_adres], nazwa mov word [cs:__1_adres+2], cs push cs db 9ah ; CALL far __1_adres dd 0 } ; sposob uzycia: ; use as follows: skacz procedure_name ; Makro generujace identyfikator urzadzenia specjalnego pod Linuksem, ; majac dane jego numer glowny i poboczny. Wynik w EDX i ESI. ; Wersja dla jader 2.6 i 2.4 ; ; A macro which generates a special device ID, given it's major and ; minor numbers. Result in EDX and ESI. Versions for kernels 2.6 and 2.4 ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro makedev26 maj*, min { if ~ min eq mov edx, min and edx, 0xff ; EDX = __minor & 0xff = 000000mm else xor edx, edx end if mov esi, maj and esi, 0xfff shl esi, 8 ; ESI = (__major & 0xfff) << 8 or edx, esi ; EDX = __minor & 0xff|(__major & 0xfff)<<8 ; EDX = 000MMMmm if ~ min eq xor eax, eax mov esi, min and esi, not 0xff shld eax, esi, 12 ; EAX = 00000mmm shl esi, 12 ; EAX:ESI = (__minor & ~0xff) << 12 ; ESI = mmm00000 else xor esi, esi end if or edx, esi ; EDX = mmmMMMmm mov esi, maj and esi, not 0xfff ; ESI = __major & ~0xfff ; ESI = MMMMM000 or esi, eax ; ESI = MMMMMmmm } macro makedev24 maj*, min { xor esi, esi mov edx, maj shl edx, 8 if ~ min eq or edx, min end if } ; sposob uzycia: ; use as follows: makedev26 254, 1 makedev24 253 ; Makro do uruchamiania funkcji wewnetrznych jadra 2.6 skompilowanego ; z regparm=3 ; ; A macro for running internal functions of a 2.6 kernel, compiled ; with regparm=3 ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro uruchom funkcja*, par1, par2, par3, par4, par5 { if ~ par5 eq push dword par5 end if if ~ par4 eq push dword par4 end if if ~ par3 eq push ecx mov ecx, par3 end if if ~ par2 eq push edx mov edx, par2 end if if ~ par1 eq push eax mov eax, par1 end if call funkcja if ~ par1 eq pop eax end if if ~ par2 eq pop edx end if if ~ par3 eq pop ecx end if if ~ par5 eq add esp, 4 end if if ~ par4 eq add esp, 4 end if } ; sposob uzycia: ; use as follows: uruchom register_chrdev, 0, nazwa, file_oper uruchom __request_region, iomem_resource, START, LEN, name ; etc. ; Makro generujace adres internetowy IP w postaci binarnej we ; wlasciwym porzadku bajtow (big-endian) z podanych czterech czesci. ; Wynik jest w EAX. ; ; A macro which generates an internet IP address in a binary form in the ; correct byte order (big-endian) from the given 4 parts. ; Result is in EAX. ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro adr2bin cz1, cz2, cz3, cz4 { xor eax, eax if ~ cz4 eq mov al, cz4 shl eax, 8 end if if ~ cz3 eq mov al, cz3 shl eax, 8 end if if ~ cz2 eq mov al, cz2 shl eax, 8 end if if ~ cz1 eq mov al, cz1 end if } ; sposob uzycia: ; use as follows: adr2bin 127, 0, 0, 1 ; adres 127.0.0.1 adr2bin 192, 168, 45, 243 ; adres 192.168.45.243 ; Makro generujace adres internetowy IP w postaci binarnej we ; wlasciwym porzadku bajtow (big-endian) z podanego lancucha znakow. ; Wynik jest w EAX. ; ; A macro which generates an internet IP address in a binary form in the ; correct byte order (big-endian) from the given string. ; Result is in EAX. ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro adrstr2bin src* { wynik = 0 cz1 = 0 cz2 = 0 cz3 = 0 cz4 = 0 ktora_teraz = 1 while 1 load X byte from src + % - 1 if X = 0 wynik = (cz4 shl 24) or (cz3 shl 16) or (cz2 shl 8) or cz1 break end if if (X > '9' | X < '0') & ~ X = '.' wynik = 0xffffffff break end if if X = '.' ktora_teraz = ktora_teraz + 1 else X = X - '0' if ktora_teraz = 1 cz1 = cz1*10 + X else if ktora_teraz = 2 cz2 = cz2*10 + X else if ktora_teraz = 3 cz3 = cz3*10 + X else if ktora_teraz = 4 cz4 = cz4*10 + X else wynik = (cz4 shl 24) or (cz3 shl 16) or (cz2 shl 8) or cz1 break end if end if if cz1 > 255 | cz2 > 255 | cz3 > 255 | cz4 > 255 wynik = 0xffffffff break end if end while mov eax, wynik } ; sposob uzycia: ; use as follows: adr1 db "127.0.0.1", 0 ; section .text adrstr2bin adr1 ; Makro zamieniajace numer portu na wlasciwy porzadek bajtowy (big-endian) ; Argument i wynik jest w EAX. ; ; A macro changing a port number to the right byte order (big-endian) ; The argument and the result is in EAX. ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro htons { and eax, 0FFFFh ror ax, 8 } ; sposob uzycia: ; use as follows: mov eax, 4242 ; internet port 4242 htons ; teraz gotowy do uzycia, np. w funkcji listen() ; now ready for use eg. by the listen() function ; Makro generujace sekcje '.gnu.linkonce.this_module' dla modulu jadra 2.6 ; ; A macro generating the '.gnu.linkonce.this_module' section for a 2.6 ; kernel module ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro gen_this_module name*, entry, exit { section '.gnu.linkonce.this_module' writeable align 128 align 128 __this_module: dd 0, 0, 0 .mod_nazwa: db name, 0 times 64-4-($-.mod_nazwa) db 0 times 100 db 0 if entry eq dd init_module else dd entry end if times 220 db 0 if exit eq dd cleanup_module else dd exit end if times 112 db 0 } ; sposob uzycia: ; use as follows: gen_this_module "nazwa_modulu", punkt_wejscia, punkt_wyjscia gen_this_module "name_of_the_module", entry_point, exit_point ; Makro zastepujace funkcje daemon z biblioteki glibc ; ; A macro substituting the daemon function from the glibc library ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro daemon nochdir, noclose { local __koniec, __dalej, __glowny, __devnull push eax push ebx push ecx push edx mov eax, 2 int 80h ; sys_fork cmp eax, 0 jl __koniec test eax, eax jz __dalej pop edx pop ecx pop ebx pop eax mov eax, 1 xor ebx, ebx int 80h ; sys_exit __glowny: db "/", 0 __devnull: db "/dev/null", 0 __dalej: mov eax, 66 ; sys_setsid int 80h cmp eax, 0 jl __koniec if nochdir = 0 mov eax, 12 ; sys_chdir mov ebx, __glowny int 80h end if if noclose = 0 mov eax, 5 ; sys_open (/dev/null) mov ebx, __devnull mov ecx, 2 mov edx, 0 int 80h cmp eax, 0 jl __koniec mov ebx, eax mov eax, 63 ; sys_dup2 mov ecx, 0 ; stdin int 80h mov eax, 63 ; sys_dup2 mov ecx, 1 ; stdout int 80h mov eax, 63 ; sys_dup2 mov ecx, 2 ; stderr int 80h mov eax, 6 ; sys_close (/dev/null) int 80h end if __koniec: pop edx pop ecx pop ebx pop eax } ; sposob uzycia: ; use as follows: daemon 1, 1 ; Makro obliczajace dlugosc lancucha znakow (zakonczonego bajtem zerowym) ; pod adresem 'src', gdzie kazdy element ma rozmiar 'size' bajtow ; (domyslnie: 1) ; ; A macro calculating the length of a string (zero-terminated) at the 'src' ; address, where each element is 'size' bytes long (default: 1) ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro strlen src*, size { ; required for "load": if src < $ len = 0 while 1 if size eq load X byte from src + (% - 1) else if size eq byte load X byte from src + (% - 1) else if size eq word load X word from src + (% - 1)*2 else if size eq dword load X dword from src + (% - 1)*4 else if size eq pword load X pword from src + (% - 1)*6 else if size eq fword load X fword from src + (% - 1)*6 else if size eq qword load X qword from src + (% - 1)*8 end if if X = 0 ; delimiter break end if len = len+1 end while dd len end if } ; sposob uzycia: ; use as follows: str1: db "AbbCCCdddd", 0 strlen str1 str2: dw 1, 2, 3, 4, 5, 6, 0 strlen str2, word ; Makro kopiujace 'n' elementow tablicy spod adresu 'src', zaczynajac od ; numeru 'pos' (uwzgledniajac rozmiar elementu), gdzie kazdy element ; ma rozmar 'size' bajtow (domyslnie: 1), pod adres 'dst'. ; ; A macro which copies 'n' array elements form the address 'src', starting ; form element number 'pos' (keeping count of the element size), ; where each element is 'size' bytes long (default: 1), to the ; address 'dst'. ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro substr src*, dst*, pos, n, size { ; required for "load": if src < $ & dst < $ if pos eq start = 0 else start = pos end if if n eq ; strlen: len = 0 while 1 if size eq load X byte from src + start + (% - 1) else if size eq byte load X byte from src + start + (% - 1) else if size eq word load X word from src + start*2 + (% - 1)*2 else if size eq dword load X dword from src + start*4 + (% - 1)*4 else if size eq pword load X pword from src + start*6 + (% - 1)*6 else if size eq fword load X fword from src + start*6 + (% - 1)*6 else if size eq qword load X qword from src + start*8 + (% - 1)*8 end if if X = 0 ; delimiter break end if len = len+1 end while else len = n end if while len > 0 if size eq load A byte from src + start + (% - 1) store byte A at dst + (% - 1) else if size eq byte load A byte from src + start + (% - 1) store byte A at dst + (% - 1) else if size eq word load A word from src + start*2 + (% - 1)*2 store word A at dst + (% - 1)*2 else if size eq dword load A dword from src + start*4 + (% - 1)*4 store dword A at dst + (% - 1)*4 else if size eq pword load A pword from src + start*6 + (% - 1)*6 store pword A at dst + (% - 1)*6 else if size eq fword load A fword from src + start*6 + (% - 1)*6 store fword A at dst + (% - 1)*6 else if size eq qword load A qword from src + start*8 + (% - 1)*8 store qword A at dst + (% - 1)*8 end if len = len - 1 end while end if } ; sposob uzycia: ; use as follows: substr str1, str2, 0, 10 substr str1, str2,,,word ; Makro odczytujace sektor o podanym numerze (1-2880) z dyskietki A: ; pod podany adres segnum:offset. ; ; A macro which reads a sector with a given number (1-2880) from the ; floppy disc A: to the specified address segnum:offset. ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro secrd numer*, segnum*, offset { local __secnum_ok push ax push bx push cx push dx push es mov ax, numer mov bx, segnum mov es, bx if offset eq xor bx, bx else mov bx, offset end if dec ax mov cl, 36 xor dx, dx div cl mov ch, al cmp ah, 18 jb __secnum_ok sub ah, 18 inc dh __secnum_ok: mov cl, ah mov ax, 0201h inc cl int 13h pop es pop dx pop cx pop bx pop ax } ; sposob uzycia: ; use as follows: secrd 1, 8000h, 0 ; bootsector ; Makro zapisujace dane znajdujace sie pod adresem segnum:offset do ; sektora dyskietki A: o podanym numerze (1-2880). ; ; A macro which writes the data located at the segnum:offset address to ; a sector of the floppy disc A: with the given sector number (1-2880). ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro secwr numer*, segnum*, offset { local __secnum_ok push ax push bx push cx push dx push es mov ax, numer mov bx, segnum mov es, bx if offset eq xor bx, bx else mov bx, offset end if dec ax mov cl, 36 xor dx, dx div cl mov ch, al cmp ah, 18 jb __secnum_ok sub ah, 18 inc dh __secnum_ok: mov cl, ah mov ax, 0301h inc cl int 13h pop es pop dx pop cx pop bx pop ax } ; sposob uzycia: ; use as follows: secwr 1, cs, xxx ; bootsector ; Makro tworzace tablice bajtow zawierajacych liczbe niezerowych bitow ; w kazdym elemencie o rozmiarze "n_bits", poczynajac od "begin". ; ; A macro which creates an array of bytes containing the number of set ; bits in every element of size "n_bits", starting with "begin". ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro gen_popcnt_array n_bits, begin { if begin eq start = 0 else if begin < 0 start = 0 else start = begin end if if n_bits eq bits = 8 else if n_bits < 0 bits = 8 else bits = n_bits end if i=start while i < (1 shl bits) j = 0 bits_set = 0 ; count the bits: while j < bits if ~ (i and (1 shl j) = 0) bits_set = bits_set + 1 end if j = j+1 end while db bits_set i = i+1 end while } ; sposob uzycia: ; use as follows: gen_popcnt_array 16 gen_popcnt_array 8, 7 ; zacznij od siodemki/start from the number 7 ; Makro kodujace tablice elementow "src" dlugosci "length" metoda ROT ; (np. ROT13), dodajac do kazdego elementu rozmiaru "size" (np. byte) ; liczbe "n" i liczac reszte z dzielenia przez "modulo" (domyslnie 256): ; X := X+n mod modulo. ; Wynik zapisywany jest do "dst" (domyslnie: "src"). ; ; A macro which encodes the "src" array of length "length" using the ROT ; algorithm (e.g. ROT13), by adding the number "n" to each element of size ; "size" (e.g byte) and calculating the remainder from division by "modulo" ; (default: 256): ; X := X+n mod modulo. ; The result is written to the array "dst" (default: "src"). ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro rot src*, length*, n*, dst, modulo, size { ; required for "load": if src < $ len = length if modulo eq m = 256 else m = modulo end if if dst eq d = src else d = dst end if while len > 0 if size eq load A byte from src + (% - 1) store byte ((A+n) mod m) at d + (% - 1) else if size eq byte load A byte from src + (% - 1) store byte ((A+n) mod m) at d + (% - 1) else if size eq word load A word from src + (% - 1)*2 store word ((A+n) mod m) at d + (% - 1)*2 else if size eq dword load A dword from src + (% - 1)*4 store dword ((A+n) mod m) at d + (% - 1)*4 else if size eq pword load A pword from src + (% - 1)*6 store pword ((A+n) mod m) at d + (% - 1)*6 else if size eq fword load A fword from src + (% - 1)*6 store fword ((A+n) mod m) at d + (% - 1)*6 else if size eq qword load A qword from src + (% - 1)*8 store qword ((A+n) mod m) at d + (% - 1)*8 end if len = len - 1 end while end if } ; sposob uzycia: ; use as follows: rot s1, 9, 2, s2, , ; Makro kodujace tablice elementow "src" dlugosci "length" metoda XOR, ; xorujac kazdy element rozmiaru "size" (np. byte) z liczba "value": ; X := X xor value. ; Wynik zapisywany jest do "dst" (domyslnie: "src"). ; ; A macro which encodes the "src" array of length "length" using the XOR ; algorithm, by xoring each element of size "size" (e.g byte) with "value": ; X := X xor value. ; The result is written to the array "dst" (default: "src"). ; ; Autor / Author: Bogdan 'bogdro' Drozdowski macro xorcod src*, length*, dst, value, size { ; required for "load": if src < $ len = length if value eq m = -1 else m = value end if if dst eq d = src else d = dst end if while len > 0 if size eq load A byte from src + (% - 1) store byte (A xor m) at d + (% - 1) else if size eq byte load A byte from src + (% - 1) store byte (A xor m) at d + (% - 1) else if size eq word load A word from src + (% - 1)*2 store word (A xor m) at d + (% - 1)*2 else if size eq dword load A dword from src + (% - 1)*4 store dword (A xor m) at d + (% - 1)*4 else if size eq pword load A pword from src + (% - 1)*6 store pword (A xor m) at d + (% - 1)*6 else if size eq fword load A fword from src + (% - 1)*6 store fword (A xor m) at d + (% - 1)*6 else if size eq qword load A qword from src + (% - 1)*8 store qword (A xor m) at d + (% - 1)*8 end if len = len - 1 end while end if } ; sposob uzycia: ; use as follows: xorcod s3, 9, s4, 0x40,