Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Низкоуровневое программирование для дZeнствующих #9


Служба Рассылок Subscribe.Ru проекта Citycat.Ru
<< УБЕЙ В СЕБЕ ЛАМЕРА

НИЗКОУРОВНЕВОЕ ПРОГРАММИРОВАНИЕ
ДЛЯ ДZЕНТСВУЮЩИХ #9

ПРЕДУПРЕЖДЕНИЯ:
ПРИГЛАШАЮТСЯ:
САЙТ HI-TECH:
> В связи с присутствием в рассылке графики настоятельно рекомендуем подписываться на HTML-версию.
> В связи с затянувшимся "расширением канала" у нашего провайдера возможны задержки с выпуском рассылки.
> авторы.
> корректоры.
> художники/дизайнеры.
> владельцы сайтов, авторы рассылок (для взаимной рекламы)
> (хм) спонсоры и рекламодатели.

> архив рассылки
> коллекция инструментов
> исходные тексты
> документация
> учебники, статьи
> форум и хм... гостевая книга

 БЛАЖЕННЫ НЕ ИМЕЮЩИЕ ИНЕТА, ИБО ИХ ЕСТЬ ЦАРСТВИЕ НЕБЕСНОЕ

   Дело было так: посмотрел сисадмин на траффик, "генерируемый" нашим "почтовым роботом", и сказал: "Я убью тебя, Serrgio"!
   Само собой, ДZенский напиток в очередной раз спас мою драгоценную жизнь, но спасти жизнь почтового робота-убийцы оказалось не под силу даже ему. А на живую огненную воду денег на тот момент не было...
   Так вот: самая большая беда заключается в том, что пока я бегал в поисках "капусты", на сисадмина наехал шеф, вследствие чего наш сисадмин впал в неблагоприятное для решения подобных вопросов состояние духа... И сколько мы с ним не дZенствовали, мне так и не удалось убедить его не обижать наших блаженных Инетом подписчиков :((.
   И знаете, что он сделал?? Убить - не убил, но придушил, надо сказать, основательно...
   Итог этих всех неприятных событий таков: "робот" теперь будет рассылать не более 50 "ответных писем" в сутки. Те, у кого действительно нет Интернета - они-то рано или поздно дождутся предыдущих номеров. А вот те, у кого Интернет есть, но они все равно захотели "нахаляву" - таким ПОЗОР и мое личное дZенское презрение...


 ПРЕДЫДУЩИЕ ВЫПУСКИ РАССЫЛКИ

   Ну не то, чтобы повторение - мать учения... просто не проштудировав материал прыдыдущих номеров, вам будет весьма затруднительно "въехать" в номер текущий...
   Выпуск 2 - про систему счисления.
   Выпуск 3 - про порядок загрузки компьютера.
   Выпуск 4 - про регистры.
   Выпуск 5 - про программу в памяти.
   Выпуск 6 - про прерывания.
   Выпуск 7 - программируем и отлаживаем.
   Выпуск 8 - "ломаем" игры, разборки со стеком, циклами, оптимизацией...
   Кстати, у кого проблемы с интернетом... хм... это только ваши проблемы и к нам по этому поводу обращаться не стоит...
   


 ВДОГОНКУ К НОМЕРУ 8 ВМЕСТЕ С ГНИЛЫМИ ПОМИДОРАМИ

   После 8-го выпуска рассылки в адрес "редакции" пришел ряд гневных писем. Типа мы тут народ взлому программного обеспечения учим. Это надо же!! Игры мы тут, понимаете ли, "кракаем" :((. Противозаконно это, видите-ли :((.
   Чушь!! Притом полная!! Противозаконным является всяческое копание в бинарнике с целью, например, обхода той или иной защиты от копирования. А то, что мы "делаем с играми" - с точки зрения текущего законодательства всех развитых, неразвитых и недоразвитых стран вполне безобидно. Так что даже и не делайте попытку на нас из-за этого наезжать...

 ЗЛОБНАЯ МИНИАТЮРКА ДЛЯ РАZОГРЕВУ

   Тут некоторым начинающим программерам CD 18 по неопытности понравилось :). Так вот, дрожащими руками ловите еще одну симпатичную миниатюрку (сразу предупреждаю, что программулька очень нехорошая):

     :0100 CLI
     :0101 JMP 0100

   А почему ей INT 20h не нужен - вы и сами догадаетесь, когда запустить попробуете...
   На WINDOWS-2000, кстати, она работает не совсем корректно ;)

 ИЗ ИНТИМНОЙ ЖИЗНИ ПРОГРАММЕРА: HEX В BIN

   Некто Алексей в гостевой книге рассказал, как на вшивость своих коллег (мега-пупер-программеров) проверял. Вопрос простой был: перевести число из HEX'а в BIN. И что же? Имея высшее-компьютерное образование, они не смогли это сделать. Не то что в уме - даже "на листике" это у них заняло весьма длительное время. Да и ответ в конце-концов был неправильный...
   Все почему-то переводили сначала их HEXа в DEC, а потом из DECа в BIN :(. А над вопросом, зачем вообще этот HEX нужен, никто и никогда, наверное, не задумывался...
   А стоило бы!!
   Всех, у кого подобные проблемы, отсылаю к выпуску #2 , особенно к п. 12.
   И не стоит забывать прописную истину, которой нас учили еще в средней школе - ПОВТОРЕНИЕ - МАТЬ УЧЕНИЯ! (Верите?)


 ПРОВЕРЬТЕ! ОН МОЮ СЕСТРУ ОБМАНУЛ...

   А еще мега-пупер-ассемблерщики наезжали. Типа лапшу мы "читателям" вешаем :). Прежде чем объяснять "политику партии" (все ж обидно, когда коллеги критикуют), мы им один простой вопрос "на крутость" задавали:
   Сколько раз выполнится следующий цикл:

  :0102 MOV CX,0000
  :0105 ADD AX,0001
  :0108 LOOP 0105

   Очевидный ответ - 0 раз. В CX же 0 у нас занесен. Так вот: ответ неправильный.
   Менее очевидный ответ - 1 раз! Ведь перед LOOP'ом сложение один раз выполнится-таки... Так вот: этот ответ тоже неправильный.
   Самые подозрительные могут сразу же посмотреть на этот цикл под отладчиком и с удивлением обнаружат, что LOOP сначала уменьшает значение CX (0-1=FFFF), а потом уже проверяет, не равен ли он нулю... И с гордостью за задний ум своей головы воскликнут: FFFFh раз!!
   Так вот: этот ответ близок к истине, но тоже неправильный ;)
   Правильный ответ - цикл выполнится 10000h (65536d) раз.
   Это тем более прикольно, что в некоторых умных книжках черным по белому сказано, что, "увы, максимум мы можем выполнить цикл FFFFh раз"...
   Но только вы и мне не верьте! Истинно только то утверждение, которое вы сами проверили на практике...

   О чем это я?? Ах да!! О "критиках"... да, в общем-то, черт с ними, с этими "критиками"... Пускай ругают, сколько хотят! У них свой путь, а у нас - свой... И если им с нами не по пути - то это только их проблемы.
   Наша же дорога трудна. В ней нет "порталов", которые помогают пересекать огромные расстояния "нахаляву", нет хорошей заасфальтрованной дороги... Есть только многочисленные указатели, один из которых посылает налево, другой направо, а третий вообще на три веселых буквы...
   А дорога такая: 86, 286, 386, 486, p, p2. С "привалами" на MMX, 3DFX и прочей "дури". Соответственно и "платформы" - сначала DOS и только потом WIN и WIN32. Оговорюсь сразу: к "звездам" - исключительно через "тернии". Правда, с многочисленными "тоже звездами" - но это от систематических ударов по голове...
   Сказано же черным по белому на сайте "старшего брата": "Рассылка "Низкоуровневое программирование для дZeнствующих" целиком посвящена программированию на ассемблере, начиная с самых фундаментальных его основ"!
   Вот мы вам и пытаемся дать ЭТО - фундаментальные основы. Ну а зачем они нужны, вы и сами знаете - чтоб крыша не поехала, чуть ветер дунет...
   А ветер - скоро дунет!! Спросите у линуксоидов...
   СЛЕДУЙ ЗА БЕЛЫМ КРОЛИКОМ!


 РАЗБОРКИ С ПРОЦЕДУРАМИ

   [1] В #7 (п. 4.) мы сделали глупую линейную программульку, выводящую окошки. Обещал я было, что в следущем выпуске мы ее сделаем менее "тупой", да отвлекся на циклы и стек почему-то... То есть я-то знаю, ПОЧЕМУ, но вот вам об этом - не скажу! Догадайтесь сами...
   Итак, поехали...
   Шаг первый. Внимательно посмотрев на "линейную" прогу из седьмого номера и прочитав "условие задачи" из п.1 вы обязаны возмутиться: зачем мы использовали команду MOV, если и ежу понятно, что отличия последующего окошка от предыдущего можно выразить более лаконично: BH=BH+10, CH=CH+1, CL=CL+1, DH=DH-1, DL=DL-1 ? И не нужно напрягать мозги, подсчитывая новое значение регистра вручную...
   Если вы так подумали, то оказались совершенно правы!!
   Программу из #7 запросто можно было представить в таком вот виде:
     
     :0100 XOR AL,AL     ;окошко первое
     :0102 MOV BH,10
     :0104 MOV CH,05
     :0106 MOV CL,10
     :0108 MOV DH,10
     :010A MOV DL,3E
     :010C MOV AH,06
     :010E INT 10
     :0110 ADD BH,10     ;окошко второе
     :0113 ADD CH,01
     :0116 ADD CL,01
     :0119 SUB DH,01
     :011C SUB DL,01
     :011F INT 10
     :0121 ADD BH,10     ;окошко третее
     :0124 ADD CH,01
     :0127 ADD CL,01
     :012A SUB DH,01
     :012D SUB DL,01
     :0130 INT 10
     :0132 ADD BH,10     ;окошко четвертое
     :0135 ADD CH,01
     :0138 ADD CL,01
     :013B SUB DH,01
     :013E SUB DL,01
     :0141 INT 10
     :0143 ADD BH,10     ;окошко пятое
     :0146 ADD CH,01
     :0149 ADD CL,01
     :014C SUB DH,01
     :014F SUB DL,01
     :0152 INT 10
     :0154 INT 20           ;конец программы

   И несмотря на то, что размер ее оказался несколько большим, она тоже будет работать правильно :)
   Но тут любой более-менее наблюдательный программер возмутится повторно: да что это за программа такая?? В ней целых 4 раза повторяется один и тот же кусок:

     :0143 ADD BH,10
     :0146 ADD CH,01
     :0149 ADD CL,01
     :014C SUB DH,01
     :014F SUB DL,01
     :0152 INT 10

   И знаете что?? Этот наблюдательный программер будет прав! А если он еще и выразится матом по поводу такого "неправильного" стиля программирование - то он будет прав АБСОЛЮТНО!

   Внимательно всмотритесь в полный текст программы и в этот выделенный кусок... И помедитируйте над ним до полного просветления текущей "обстановки"...

   [2] Итак, у нас есть ПОВТОРЯЮЩАЯСЯ ЧАСТЬ программы. А еще у нас есть пальцы, которым, как правило, лень набивать длинные "простыни" программного кода. Это одна из многочисленных причин, по которым и придумали такого зверя, как ПРОЦЕДУРУ (она же - ПОДПРОГРАММА). Остальные причины, мы рассмотрим попозже, а вот на счет "лени" поговорим прямо сейчас:
   Если мы возмем наш частоповторяющийся кусок программы и допишем в ее конец команду RET, то получится у нас именно ПРОЦЕДУРА - во всей своей красе...
 
     :011E ADD BH,10   ;"точка входа"; она же - начало "тела".
     :0121 ADD CH,01
     :0124 ADD CL,01
     :0127 SUB DH,01
     :012A SUB DL,01
     :012D INT 10        ;конец "тела"
     :012F RET
   
   Красота ее вот в чем заключается: процедуру можно "вызвать" командой CALL :)))
   Все более чем просто :). Когда в программе встречается CALL с указанием АДРЕСА-НАЧАЛА-ПРОЦЕДУРЫ (в нашем случае это 011E), то "компьютер" "идет" по этому адресу и выполняет все команды, ресположенные между "точкой входа" (включительно) и командой RET, то есть так называемое "тело" процедуры.
   RET - это тоже команда, но к "телу" (адреса 11E... 12D) она не относится. Она является "ОРГАНИЗАТОРОМ" этого "тела". Процессор, встретив команду RET, "перепрыгивает" на строчку ниже "вызвавшего" данную процедуру CALL'а...
   Короче: CALL XXXX - означает "выполнить процедуру, начинающуюся по адресу XXXX". А RET - означет "конец процедуры" и, соответственно, переход на строчку ниже вызвавшего его CALL'а.
   Не ругайтесь. Я знаю, что вы ничерта не поняли. А по сему набьем в debug'е эту прогу и посмотрим, что она делает...

   [3] Кстати, вы уже поняли, почему я называю debug "до боли любимой программой"? Нет?? Неужели вы еще не полюбили это произведение программерского гения всеми фибрами своей души?
   Еще нет??
   М-да... я вас разочаровался... А по сему:
   "НАБИВАЕМ!" - злобно кричу я вам, брызгая слюной на свой эргономичный коврик...

    :0100 XOR AL,AL    ;первое окошко рисуем, как и раньше...
    :0102 MOV BH,10
    :0104 MOV CH,05
    :0106 MOV CL,10
    :0108 MOV DH,10
    :010A MOV DL,3E
    :010C MOV AH,06
    :010E INT 10
    :0110 CALL 011E    ;четыре раза вызываем подпрограмму, начинающуюся
    :0113 CALL 011E    ;по адресу 011E
    :0116 CALL 011E
    :0119 CALL 011E
    :011C INT 20         ;выход из программы...
    :011E ADD BH,10    ;начало процедуры
    :0121 ADD CH,01
    :0124 ADD CL,01
    :0127 SUB DH,01
    :012A SUB DL,01
    :012D INT 10
    :012F RET             ;конец процедуры
   
   Не правда ли, красиво получилось??
   А то!

   Первое, что вас может смутить, это то, что команда выхода (INT 20) расположена не там, где вы привыкли, то есть не в конце программы.
   Ну что я вам могу на это ответить? Концы-то - они разные бывают! Последняя строчка в листинге вовсе не означает, что последней будет выполняться именно она. И это не должно вас смущать!! А если все-же смущает - смотрим, как работает эта прога из-под отладчика...
   Итак, до адреса 0110 вам все должно быть понятно. Мы это рассматривали. Трассируем дальше...
   Команда CALL 011E по адресу 0110 говорит поцессору: "дальше мы не пойдем, пока не выполним простыню, начинающуюся по адресу 011E"; и далее, естественно, следует переход на этот адрес.
   Входим в тело процедуры, начиная с 011E и выполняем команды до 012D включительно...
   А теперь внимательно смотрим, на какой адрес нас "перекинет" команда RET.
   На 113-й? И это правильно!
   По 113-му адресу у нас какая команда? Да вот опять CALL 011E!
   Опять процедура с адреса 011E, опять RET[URN] на строку ниже, то есть на 116...
   И так далее до того момента, пока следующей строчкой не окажется INT 20 - собственно, на этом и программе конец.
   Ну оно и ежу понятно, что несмотря на то, что INT 20 - не в конце программы, последним выполнится именно он.
   Короче, куда бы вас не посылали всяческие "столбы с указателями", конец вашего пути только один - ГРОБ. А плутать вокруг да около этого гроба вы можете сколько вам заблагорассудится...

   Кстати, именно это и является одной из многочисленных тайн структурного программинга...
   Кто после этого скажет, что программисты - не дZенствующие люди??

   [4] Те, кто читал прошлый номер, они и на этом не остановятся!! Посмотрев на адреса 110...119, они вообще возьмут и возомнят себя воистину крутыми парнями!
   Знаете, что они напишут??
   А вот что (предвижу!):

    :0100 XOR AL,AL
    :0102 MOV BH,10
    :0104 MOV CH,05
    :0106 MOV CL,10
    :0108 MOV DH,10
    :010A MOV DL,3E
    :010C MOV AH,06
    :010E INT 10
    :0110 MOV CX,0004
    :0113 CALL 011A
    :0116 LOOP 0113
    :0118 INT 20
    :011A ADD BH,10
    :011D ADD CH,01
    :0120 ADD CL,01
    :0123 SUB DH,01
    :0126 SUB DL,01
    :0129 INT 10
    :012B RET

   То бишь еще и CALL в цикл при помощи MOV CX,4 и LOOP'а "закрутят". И что? А попробуйте!
   Что, не "пашет"? А что надо делать, если "не пашет, а должно бы"? Правильно! Смотреть из-под отладчика!
   Смотрим? Если посмотрите, то сразу же и "загвоздку" увидите! CX, использованный в качестве "счетчика" циклов, "перебивает" тот же CX, но используемый как "координаты верхнего левого угла окна". И что с этим делать прикажете??
   Вот... вы столкнулись с одной из самых больших проблем. В компьютере есть только 4 переменные, помните я вам говорил об этом?
   И теперь догадайтесь, как выкрутиться из этой нехорошей ситуации с использованием стека??

   В общем, вот что: медитируйте-ка вы до следующей недели, а там посмотрим :)


 АНОНС!

   Это Нового года может не быть! Следующий номер рассылки - будет! Даже если мне на голову еще один кирпич свалится... - следующий номер все равно будет!!
   Может по-приколу с наступающим новым тысячелетием всех поздравить?
   Не хочу и не буду!
   Потому что после последнего милениума, с которым я сталкивался, меня до сих пор к окну тянет... осовободиться, понимаете ли, от излишних несовместимых компонентов... самой крутой... самой опера... ционной... системы ... тысяче... ле..... сяче... и.......
   ДА НЕ НАКАРКАЕТ НАМ БИЛЛГЕЙТС БЕДЫ СВОИМ WINDOWS-MILLENIUM'ом!
   Крепите дух, братья! Нас ждут страшные годы...


serrgio@gorki.unibel.by / ICQ: 63813760 / Приятного вам дZенствования!!


http://subscribe.ru/
E-mail: ask@subscribe.ru
Поиск

В избранное