А.В. Столяров - Программирование на языке ассемблера NASM для ОС Unix (1110582), страница 26
Текст из файла (страница 26)
×òîáû íàì íå ïðèøëîñü ïî íåñêîëüêî ðàç ñòèðàòü ýòè ñîîáùåíèÿ è âñòàâëÿòüèõ ñíîâà, âîñïîëüçóåìñÿ äèðåêòèâàìè óñëîâíîé êîìïèëÿöèè. Âûãëÿäåòüýòî áóäåò ïðèìåðíî òàê:%ifdef DEBUG_PRINTPRINT "Entering suspicious section"PUTCHAR 10%endif;;çäåñü èä¼ò "ïîäîçðèòåëüíàÿ" ÷àñòü ïðîãðàììû;%ifdef DEBUG_PRINTPRINT "Leaving suspicious section"PUTCHAR 10111%endifÇäåñü %ifdef ýòî îäíà èç äèðåêòèâ óñëîâíîé êîìïèëÿöèè , îçíà÷àþùàÿ ¾êîìïèëèðîâàòü òîëüêî â ñëó÷àå, åñëè îïðåäåë¼í äàííûé îäíîñòðî÷íûé ìàêðîñ¿ (â äàííîì ñëó÷àå ýòî ìàêðîñ DEBUG_PRINT). Òåïåðü âíà÷àëî ïðîãðàììû ñëåäóåò âñòàâèòü ñòðîêó, îïðåäåëÿþùóþ ýòîò ñèìâîë:%define DEBUG_PRINTÒîãäà ïðè çàïóñêå NASM ¾óâèäèò¿ è îòêîìïèëèðóåò ôðàãìåíòû íàøåãî èñõîäíîãî òåêñòà, çàêëþ÷¼ííûå ìåæäó ñîîòâåòñòâóþùèìè %ifdef è%endif; êîãäà æå ìû íàéä¼ì îøèáêó è îòëàäî÷íàÿ ïå÷àòü áóäåò íàìáîëüøå íå íóæíà, äîñòàòî÷íî áóäåò óáðàòü ýòîò %define èç íà÷àëà ïðîãðàììû èëè äàæå ïîñòàâèòü ïåðåä íèì çíàê êîììåíòàðèÿ:;%define DEBUG_PRINTè ôðàãìåíòû, îáðàìë¼ííûå ñîîòâåòñòâóþùèìè äèðåêòèâàìè, ìàêðîïðîöåññîð áóäåò ïîïðîñòó èãíîðèðîâàòü, òàê ÷òî èõ ìîæíî ñîâåðøåííî ñïîêîéíî îñòàâèòü â òåêñòå ïðîãðàììû, à íå óäàëÿòü, íà ñëó÷àé, åñëè îíèñíîâà ïîíàäîáÿòñÿ.Çàáåãàÿ âïåð¼ä, îòìåòèì, ÷òî äëÿ âêëþ÷åíèÿ è îòêëþ÷åíèÿ îòëàäî÷íîé ïå÷àòè, îôîðìëåííîé òàêèì îáðàçîì, ìîæíî âîîáùå îáîéòèñü áåç ïðàâêè èñõîäíîãî òåêñòà.
Îïðåäåëèòü ìàêðîñèìâîë ìîæíî êëþ÷îì êîìàíäíîé ñòðîêè NASM; â÷àñòíîñòè, âêëþ÷èòü îòëàäî÷íóþ ïå÷àòü èç íàøåãî ïðèìåðà ìîæíî, âûçâàâ NASMïðèìåðíî òàêèì îáðàçîì:nasm -f elf -dDEBUG_PRINT prog.asm÷òî èçáàâëÿåò íàñ îò íåîáõîäèìîñòè âñòàâëÿòü â èñõîäíûé òåêñò äèðåêòèâó%define, à ïîòîì å¼ óäàëÿòü.Âîçâðàùàÿñü ê ñèòóàöèè ñ äâóìÿ çàêàç÷èêàìè, ìû ìîæåì ïðåäóñìîòðåòü â ïðîãðàììå êîíñòðóêöèè, ïîäîáíûå ñëåäóþùåé:%ifdef FOR_PETROV;; çäåñü êîä, ïðåäíàçíà÷åííûé òîëüêî äëÿ Ïåòðîâà;%elifdef FOR_SIDOROV;; à çäåñü - òîëüêî äëÿ Ñèäîðîâà;%else; åñëè íè òîò ñèìâîë, íè äðóãîé íå îïðåäåëåíû,; ïðåðâ¼ì êîìïèëÿöèþ è âûäàäèì ñîîáùåíèå îá îøèáêå%error Please define either FOR_PETROV or FOR_SIDOROV%endif112(äèðåêòèâà %elifdef ýòî ñîêðàù¼ííàÿ ôîðìà çàïèñè äëÿ else èifdef). Ïðè êîìïèëÿöèè òàêîé ïðîãðàììû íóæíî áóäåò îáÿçàòåëüíî óêàçàòü êëþ÷ -dFOR_PETROV èëè -dFOR_SIDOROV, èíà÷å NASM íà÷í¼ò îáðàáàòûâàòü ôðàãìåíò, íàõîäÿùèéñÿ ïîñëå %else, è, âñòðåòèâ äèðåêòèâó%error, âûäàñò ñîîáùåíèå îá îøèáêå.Êðîìå ïðîâåðêè íàëè÷èÿ ìàêðîñèìâîëà, ìîæíî ïðîâåðÿòü òàêæå èôàêò îòñóòñòâèÿ ìàêðîñèìâîëà (òî åñòü ïðÿìî ïðîòèâîïîëîæíîå óñëîâèå).
Ýòî äåëàåòñÿ äèðåêòèâîé %ifndef (if not dened ). Êàê è äëÿ %ifdef,äëÿ %ifndef ñóùåñòâóåò ñîêðàù¼ííàÿ çàïèñü êîíñòðóêöèè ñ %else, îíàíàçûâàåòñÿ %elifndef.Äëÿ çàäàíèÿ óñëîâèÿ, ïðè êîòîðîì òîò èëè èíîé ôðàãìåíò ïîäëåæèòèëè íå ïîäëåæèò êîìïèëÿöèè, ìîæíî ïîëüçîâàòüñÿ íå òîëüêî ôàêòîìíàëè÷èÿ èëè îòñóòñòâèÿ ìàêðîñà; NASM ïîääåðæèâàåò è äðóãèå äèðåêòèâû óñëîâíîé êîìïèëÿöèè. Íàèáîëåå îáùåé ÿâëÿåòñÿ äèðåêòèâà %if, âêîòîðîé óñëîâèå çàäà¼òñÿ àðèôìåòèêî-ëîãè÷åñêèì âûðàæåíèåì, âû÷èñëÿåìûì âî âðåìÿ êîìïèëÿöèè. Ñ òàêèìè âûðàæåíèÿìè ìû óæå âñòðå÷àëèñü â 3.4.1; äëÿ ôîðìèðîâàíèÿ ëîãè÷åñêèõ âûðàæåíèé íàáîð äîïóñòèìûõ îïåðàöèé ðàñøèðÿåòñÿ îïåðàöèÿìè =, <, >, >=, <=, â èõ îáû÷íîìñìûñëå, îïåðàöèþ ¾íå ðàâíî¿ ìîæíî çàäàòü ñèìâîëîì <>, êàê â Ïàñêàëå,èëè ñèìâîëîì !=, êàê â Ñè; ïîääåðæèâàåòñÿ è Ñè-ïîäîáíàÿ ôîðìà çàïèñèîïåðàöèè ¾ðàâíî¿ â âèäå äâóõ çíàêîâ ðàâåíñòâà ==.
Êðîìå òîãî, äîñòóïíû ëîãè÷åñêèå ñâÿçêè && (¾è¿), || (¾èëè¿) è ^^ (¾èñêëþ÷àþùåå èëè¿).Îòìåòèì, ÷òî âñå âûðàæåíèÿ, èñïîëüçóåìûå â äèðåêòèâå %if, ðàññìàòðèâàþòñÿ êàê êðèòè÷åñêèå (ñì. 3.4.2). Òàê æå, êàê è äëÿ âñåõ îñòàëüíûõ%if-äèðåêòèâ, äëÿ ïðîñòîãî %if èìååòñÿ ôîðìà ñîêðàù¼ííîé çàïèñè êîíñòðóêöèè ñ %else äèðåêòèâà %elif.Ïåðå÷èñëèì êðàòêî îñòàëüíûå ïîääåðæèâàåìûå NASM óñëîâíûå äèðåêòèâû. Äèðåêòèâû %ifidn è %ifidni ïðèíèìàþò äâà àðãóìåíòà, ðàçäåë¼ííûå çàïÿòîé, è ñðàâíèâàþò èõ êàê ñòðîêè, ïðåäâàðèòåëüíî ïðîèçâåäÿ, åñëè ýòî íåîáõîäèìî, ìàêðîïîäñòàíîâêè â òåêñòå àðãóìåíòîâ.
Ôðàãìåíò êîäà, ñëåäóþùèé çà ýòèìè äèðåêòèâàìè, òðàíñëèðóåòñÿ òîëüêî âñëó÷àå, åñëè ñòðîêè îêàæóòñÿ ðàâíûìè, ïðè÷¼ì %ifidn òðåáóåò òî÷íîãî ñîâïàäåíèÿ, òîãäà êàê %ifidni èãíîðèðóåò ðåãèñòð è ñ÷èòàåò, íàïðèìåð, ñòðîêè foobar, FooBar è FOOBAR îäèíàêîâûìè. Äëÿ ïðîâåðêèïðîòèâîïîëîæíîãî óñëîâèÿ ìîæíî èñïîëüçîâàòü äèðåêòèâû %ifnidn è%ifnidni; âñå ÷åòûðå äèðåêòèâû èìåþò %elif-ôîðìû, ñîîòâåòñòâåííî,%elifidn, %elifidni, %elifnidn è %elifnidni.
Äèðåêòèâà %ifmacro ïðîâåðÿåò ñóùåñòâîâàíèå ìíîãîñòðî÷íîãî ìàêðîñà; ïîääåðæèâàþòñÿ äèðåêòèâû %ifnmacro, %elifmacro è %elifnmacro. Äèðåêòèâû %ifid, %ifstr è%ifnum ïðîâåðÿþò, ÿâëÿåòñÿ ëè èõ àðãóìåíò, ñîîòâåòñòâåííî, èäåíòèôèêàòîðîì, ñòðîêîé èëè ÷èñëîâîé êîíñòàíòîé. Êàê îáû÷íî, NASM ïîääåðæèâàåò âñå äîïîëíèòåëüíûå ôîðìû âèäà %ifnXXX, %elifXXX è %elifnXXXäëÿ âñåõ òð¼õ äèðåêòèâ.113Êðîìå ïåðå÷èñëåííûõ, NASM ïîääåðæèâàåò äèðåêòèâó %ifctx è ñîîòâåòñòâóþùèå ôîðìû, íî îáúÿñíåíèå å¼ ðàáîòû äîñòàòî÷íî ñëîæíî è îáñóæäàòü ýòó äèðåêòèâó ìû íå áóäåì. 3.5.5. ÌàêðîïîâòîðåíèÿÏðè íåîáõîäèìîñòè ïðåïðîöåññîð NASM ìîæíî çàñòàâèòü ìíîãîêðàòíî (öèêëè÷åñêè) îáðàáàòûâàòü îäèí è òîò æå ôðàãìåíò êîäà.
Ýòî äîñòèãàåòñÿ äèðåêòèâàìè %rep (îò ñëîâà repetition ) è %endrep. Äèðåêòèâà %rep ïðèíèìàåò îäèí îáÿçàòåëüíûé ïàðàìåòð, îçíà÷àþùèé êîëè÷åñòâî ïîâòîðåíèé. Ôðàãìåíò êîäà, çàêëþ÷¼ííûé ìåæäó äèðåêòèâàìè %repè %endrep, áóäåò îáðàáîòàí ìàêðîïðîöåññîðîì (è àññåìáëåðîì) ñòîëüêîðàç, ñêîëüêî óêàçàíî â ïàðàìåòðå äèðåêòèâû %rep. Êðîìå òîãî, ìåæäóäèðåêòèâàìè %rep è %endrep ìîæåò âñòðåòèòüñÿ äèðåêòèâà %exitrep, êîòîðàÿ äîñðî÷íî ïðåêðàùàåò âûïîëíåíèå ìàêðîïîâòîðåíèÿ. Ðàññìîòðèìïðîñòîé ïðèìåð. Ïóñòü íàì íåîáõîäèìî îïèñàòü îáëàñòü ïàìÿòè, ñîñòîÿùóþ èç 100 ïîñëåäîâàòåëüíûõ áàéòîâ, ïðè÷¼ì â ïåðâîì èç íèõ äîëæíîñîäåðæàòüñÿ ÷èñëî 50, âî âòîðîì ÷èñëî 51 è ò.
ä., â ïîñëåäíåì, ñîîòâåòñòâåííî, ÷èñëî 149. Êîíå÷íî, ìîæíî ïðîñòî íàïèñàòü ñòî ñòðîê êîäà:db 50db 51db 52;....db 148db 149íî ýòî, âî-ïåðâûõ, óòîìèòåëüíî, à âî-âòîðûõ, çàíèìàåò ñëèøêîì ìíîãîìåñòà â òåêñòå ïðîãðàììû. Ãîðàçäî ïðàâèëüíåå áóäåò ïîðó÷èòü ãåíåðàöèþ ýòîãî êîäà ìàêðîïðîöåññîðó, âîñïîëüçîâàâøèñü ìàêðîïîâòîðåíèåìè ìàêðîïåðåìåííîé:%assign n 50%rep 100db n%assign n n+1%endrepÂñòðåòèâ òàêîé ôðàãìåíò, ìàêðîïðîöåññîð ñíà÷àëà ñâÿæåò ñ ìàêðîïåðåìåííîé n çíà÷åíèå 50, çàòåì ñòî ðàç ðàññìîòðèò äâå ñòðî÷êè, çàêëþ÷¼ííûå ìåæäó %rep è %endrep, ïðè÷¼ì êàæäîå ðàññìîòðåíèå ýòèõ ñòðîêïðèâåä¼ò ê ãåíåðàöèè î÷åðåäíîé ïîäëåæàùåé àññåìáëèðîâàíèþ ñòðîêèdb 50, db 51, db 52 è ò.
ä.; èçìåíåíèå ÷èñëà ïðîèñõîäèò áëàãîäàðÿ òîìó,÷òî çíà÷åíèå ìàêðîïåðåìåííîé n èçìåíÿåòñÿ (óâåëè÷èâàåòñÿ íà åäèíèöó)114íà êàæäîì ïðîõîäå ìàêðîïîâòîðåíèÿ. Èíà÷å ãîâîðÿ, â ðåçóëüòàòå îáðàáîòêè ìàêðîïðîöåññîðîì ýòîãî ôðàãìåíòà êàê ðàç è ïîëó÷àòñÿ òî÷íîòàêèå ñòî ñòðîê êîäà, êàê ïîêàçàíî âûøå, è èìåííî îíè è áóäóò àññåìáëèðîâàòüñÿ. Ìàêðîïðîöåññîð, òàêèì îáðàçîì, èçáàâëÿåò íàñ îò íåîáõîäèìîñòè ïèñàòü ýòè ñòî ñòðîê âðó÷íóþ.Ðàññìîòðèì áîëåå ñëîæíûé ïðèìåð. Ïóñòü èìååòñÿ íåîáõîäèìîñòü çàäàòü îáëàñòü ïàìÿòè, ñîäåðæàùóþ ïîñëåäîâàòåëüíî â âèäå ÷åòûð¼õáàéòíûõ öåëûõ âñå ÷èñëà Ôèáîíà÷÷è8 , íå ïðåâîñõîäÿùèå 100000.
Ñãåíåðèðîâàòü ñîîòâåòñòâóþùóþ ïîñëåäîâàòåëüíîñòü äèðåêòèâ dd ìîæíî ñ ïîìîùüþ òàêîãî ôðàãìåíòà êîäà:fibonacci%assign i 1%assign j 1%rep 100000%if j > 100000%exitrep%endifdd j%assign k%assign i%assign j%endrepfib_countequj+ijk($-fibonacci)/4ïðè÷¼ì ìåòêà fibonacci áóäåò ñâÿçàíà ñ àäðåñîì íà÷àëà ñãåíåðèðîâàííîé îáëàñòè ïàìÿòè, à ìåòêà fib_count ñ îáùèì êîëè÷åñòâîì ÷èñåë,ðàçìåù¼ííûõ â ýòîé îáëàñòè ïàìÿòè (ñ ýòèì ïðè¼ìîì ìû óæå ñòàëêèâàëèñü íà ñòð. 98).Èñïîëüçîâàòü ìàêðîïîâòîðåíèÿ ìîæíî íå òîëüêî äëÿ ãåíåðàöèè îáëàñòåé ïàìÿòè, çàïîëíåííûõ ÷èñëàìè, íî è äëÿ äðóãèõ öåëåé.
Ïóñòü,íàïðèìåð, ó íàñ èìååòñÿ ìàññèâ èç 128 äâóõáàéòîâûõ öåëûõ ÷èñåë:arrayresw 128è ìû õîòèì íàïèñàòü ïîñëåäîâàòåëüíîñòü èç 128 êîìàíä inc, óâåëè÷èâàþùèõ íà åäèíèöó êàæäûé èç ýëåìåíòîâ ýòîãî ìàññèâà. Ìîæíî ñäåëàòüýòî òàê:%assign a array8 Íàïîìíèì, ÷òî ÷èñëà Ôèáîíà÷÷è ýòî ïîñëåäîâàòåëüíîñòü ÷èñåë, íà÷èíàþùàÿñÿñ äâóõ åäèíèö, êàæäîå ñëåäóþùåå ÷èñëî êîòîðîé ïîëó÷àåòñÿ ñëîæåíèåì äâóõ ïðåäûäóùèõ: 1, 1, 2, 3, 5, 8, 13, 41, 34 è ò. ä.115%rep 128inc word [a]%assign a a+2%endrep×èòàòåëü ìîã áû îòìåòèòü, ÷òî èñïîëüçîâàíèå â òàêîé ñèòóàöèè 128 êîìàíäíåðàöèîíàëüíî è ïðàâèëüíåå áûëî áû âîñïîëüçîâàòüñÿ öèêëîì âî âðåìÿ èñïîëíåíèÿ, íàïðèìåð, òàê:lp:mov ecx, 128inc word [array + ecx*2 - 2]loop lp áîëüøèíñòâå ñëó÷àåâ òàêîé âàðèàíò äåéñòâèòåëüíî ïðåäïî÷òèòåëüíåå, ïîñêîëüêó òàêèå òðè êîìàíäû, åñòåñòâåííî, áóäóò çàíèìàòü â íåñêîëüêî äåñÿòêîâ ðàçìåíüøå ïàìÿòè, ÷åì ïîñëåäîâàòåëüíîñòü èç 128 êîìàíä inc, íî ñëåäóåò èìåòüâ âèäó, ÷òî ðàáîòàòü òàêîé êîä áóäåò ïðèìåðíî â ïîëòîðà ðàçà ìåäëåííåå, òàê÷òî â íåêîòîðûõ ñëó÷àÿõ ïðèìåíåíèå ìàêðîöèêëà äëÿ ãåíåðàöèè ïîñëåäîâàòåëüíîñòè îäèíàêîâûõ êîìàíä (âìåñòî öèêëà âðåìåíè èñïîëíåíèÿ) ìîæåò îêàçàòüñÿîñìûñëåííûì. 3.5.6.
Ìíîãîñòðî÷íûå ìàêðîñû è ëîêàëüíûå ìåòêèÂåðí¼ìñÿ òåïåðü ê ìíîãîñòðî÷íûì ìàêðîñàì; òàêèå ìàêðîñû ãåíåðèðóþò íå ôðàãìåíò ñòðîêè, à ôðàãìåíò òåêñòà, ñîñòîÿùèé èç íåñêîëüêèõñòðîê. Îïèñàíèå ìíîãîñòðî÷íîãî ìàêðîñà òàêæå ñîñòîèò èç íåñêîëüêèõñòðîê, çàêëþ÷¼ííûõ ìåæäó äèðåêòèâàìè %macro è %endmacro.  3.5.2ìû óæå ðàññìàòðèâàëè ïðîñòåéøèå ïðèìåðû ìíîãîñòðî÷íûõ ìàêðîñîâ,îäíàêî â ìàëî-ìàëüñêè ñëîæíîì ñëó÷àå ðàññìîòðåííûõ ñðåäñòâ íàì íåõâàòèò. Ïóñòü, íàïðèìåð, ìû õîòèì îïèñàòü ìàêðîñ zeromem, ïðèíèìàþùèé íà âõîä äâà ïàðàìåòðà àäðåñ è äëèíó îáëàñòè ïàìÿòè è ðàñêðûâàþùèéñÿ â êîä, çàïîëíÿþùèé ýòó ïàìÿòü íóëÿìè.
Íå îñîáåííî çàäóìûâàÿñü íàä ïðîèñõîäÿùèì, ìû ìîãëè áû íàïèñàòü, íàïðèìåð, ñëåäóþùèé(íåïðàâèëüíûé!) êîä:%macro zeromem 2push ecxpush esimov ecx,mov esi,lp:mov byteinc esiloop lppop esipop ecx%endmacro; (äâà ïàðàìåòðà - àäðåñ è äëèíà)%2%1[esi], 0116NASM ïðèìåò òàêîå îïèñàíèå è äàæå ïîçâîëèò ïðîèçâåñòè îäèí ìàêðîâûçîâ.