Spojení C a NASM pod GNU/Linuxem

Kategorie: IT/Security | Zobrazen: 13049x Datum: 21.12.2007

Praktická ukázka programu, jehož interface je naprogramován v jazyce C, zatímto hlavní funkce je realizovaná v jazyce assembleru, konkrétněji NASM.

Kvadratická rovnice v jazyce assembler

Ještě předím, než jsem se pustil do psaní tohoto článku, jsem dlouho rozmýšlel nad jeho názvem. V úvahu připadal současný název a pak "Kvadratická rovnice v jazyce assembler". Tím jsem nechtěně prozradil, že předváděný program bude mít na starosti řešení kořenů obyčejné kvadratické rovnice. Ve vyšším programovacím jazyce by byl takový program otázkou několika málo minut. V assembleru je však mírně složitější. Aby řešení rovnice nebylo tak triviální, implementoval jsem také řešení v oboru komplexních čísel, tedy v případě, že diskriminant kvadratické rovnice vyjde záporné číslo.

Dětský sen

Své prográtorské začátky jsem zmínil již v úvodu k článku Hra had v jazyce C a nyní volně naváži. K assebleru jsem se dostal přibližně v polovině třetího ročníku gymnázia. Nejdříve jsem sháněl informace na internetu a později mi byla velkým pomocníkem kniha Rudolfa Marka Učíme se programovat v jazyce Assembler pro PC, která je zároveň doporučenou četbou předmětu Asemblery, který v tomto semestru máme na FIT VUT. Původně, když se mi hlavě zrodil nápad začít se učit jazyk assebler, jsem si dal cíl, že v něm naprogramuji program na řešení kvadratické rovnice. Tehdy jsem neměl ještě žádné tušení o exotické syntaxi jazyka a o komplikacích při práci s reálnými čisli. Proto jsem brzy narazil. Vrcholem byl program, který uživatele vyzval ke vstupu dvou čísel, ty následně sečetl a vypsal. Je ale nutno říci, že funkce na vstup a výstup řetezce, konverzi řetězce na číslo a naopak jsem si napsal sám. Právě to bylo na tom programu to nejnáročnější, samotné sečtění čísel pak už bylo formalitou. Jednoduše jsem neměl k dispozici připravené funkce printf, scanf či atoi a o předpřipravených makrech jsem potuchy moc neměl. Tento program jsem tedy vzal jako vrchol svého programování v tomto jazyce a na assembler jsem na delší dobu zanevřel. Když odskočím zpět do součastnosti, je vlastně tento program takovým pomyslným splněním mého "dětského snu", že si naprogramuji kvadratickou rovnici v assembleru.

Nepřestal mě fascinovat

Sice jsem výše psal, že jsem na assembler zanevřel, to ale neznamená, že jsem ho přestal mít rád a že mě přestal fascinovat. O prázdninách po maturitě jsem zkoušel slasti a strasti Reverse Engeneeringu, ke kterému je znalost assebleru klíčová. Ve většině případů však nešlo o to vytvářet vlatní asm programy, ale o to pochopit cizí asm kód. V tomto ohledu mi toto období dalo hodně. Poté přislo VUT a předmět asemblery, kde jsem si zopakoval základy a navíc se naučil i FPU, které je například k řešení kořenů kvadratické rovnice nezbytné.

Vlastní implementace

Tak konec vzpomínání a zpět k realitě. Jak říká jedno moudré přísloví (no asi to ale není přísloví): "Jeden příklad řekne více než sto slov". Proto zájemce o vlastní implementaci odkáži rovnou na archiv se zdrojovými kódy. Archiv obsahuje soubor main.c, ve kterém se nachází interface programu, soubor assebler.asm, ve kterém je definice vlastní funkce počítající kořeny kvadratické rovnice a soubor Makefile. Céčkovský soubor je podle mě velmi srozumitelný a nebylo jej třeba ani komentovat. Naproti tomu soubor s asm jsem se snažil komentovat co nejvíce a k jeho pochopení je nezbytná alespoň základní znalost FPU. V souboru main.c je funkce kvrov deklarována jako extern, což znamená, že se její tělo nachází mimo tento soubor. Naopak v souboru assembler.asm má před sebou funkce kvrov klíčové slovo global, což značí, že její definice bude dostupná i mimo tento soubor. Kompilace programu proběhne následovně v tomto pořadí:

Resume

Z přiloženého příkladu je podle mě celé propojení jasné, případné dotazy můžete psát do komentářů. Na závěr bych chtěl podotknout, že snad všechny assemblery (ve smyslu programovacího jazyka) jsou propojitelné s vyššími programovacími jazyky. Ptáte se tedy proč zrovna NASM? Hlavně proto, že je multiplatformní a korektně funguje pod GNU/Linuxem a samozřejmě i proto, že na tomto assembleru jsem se kdysi učil základy a nyní je i probírán na FIT VUT v prvním semestru.

Download:

kvarov.tar.gz

kvrov.zip

Update 4.1.2008: V rámci přípravy na semestrální zkoušku z IAS jsem udělal ještě jeden program, který provádí různé operace s polem. Znovu se jedná o program v C s tím, že jednotlivé funkce jsou implementovány v NASM. Třeba vám to pomůže...

pole.tar.gz

pole.zip

A tady další... Tentokrát implementace funkce strcmp v NASM spolupracující s C programem.

strcmp.tar.gz

strcmp.zip

A dále různé implementace této funkce:

a) Funkce považuje velká a malá písmena (anglické abecedy) za shodná (tj. řetězce "Ahoj" a "ahoj" jsou shodné)

strcmp_a.tar.gz

strcmp_a.zip

b) Funkce předpokládá, že znak '?' je shodný s jakýmkoliv znakem (řetězce "Ah?j" a "?h?j" jsou shodné)

strcmp_b.tar.gz

strcmp_b.zip

c) Funkce předpokládá, že znak '?' je shodný s jakýmkoliv písmenem anglické abecedy (řetězce "Ahoj2" a "?h?j2" jsou shodné, řetězce "Ahoj2" a "Ahoj?" nejsou shodné)

strcmp_c.tar.gz

strcmp_c.zip

d) Funkce má přidán třetí parametr: int strcmp (char *s1, char *s2, int len) a porovnává řetězce v délce maximálně len znaků (řetězce mohou být kratší !)

strcmp_d.tar.gz

strcmp_d.zip

A další nyní bylo zadání takovéto: Napište vzdálenou (far) proceduru, void my_proc(char *p1, char *p2, int d1, int d2) s volací posloupností jazyka C, která zkopíruje druhé pole na začátek prvního (hodnoty prvního pole odsune).

pole_copy.tar.gz

pole_copy.zip

Stoyan's signature

Předcházející článek: FIT VUT dojmy po půl roce

Následující článek: Jsem šachovým mistrem Evropy

Libí se vám tento článek? Zalinkujte ho: Linkuj tento článek
© Stoyan, 2006 - 2016