Воробьёвы

(-:

№7. Поздравления, фак, пришло время программировать

ПРИНИМАЕМ ПОЗДРАВЛЕНИЯ!! (ВСЕМ ЛЬЕМ ПИВО В МОДЕМ)

7 декабря 2000 года авторский коллектив HI-TECH имел счастие упиться напитком дZен, в простонародии именуемым также пИвом. ДZенствовали мы весь вечер, коий впоследствие плавно перешел в диалектическую ночь а затем и в не менее галимое утро завтрашнего дня... ик...

Вот по какому поводу это было:

После долгих и продолжительных боев с мелкими техническими недоработками и прочей хренотенью рассылке "Низкоуровневое программирование для дZенствующих" была присвоена категория "обычные некоммерческие рассылки", с чем авторы оной сами себя всю ночь и поздравляли :))

Что это значит? А то, что теперь мы - не в категории "рассылки для каждого". Теперь мы - "серебрянные"! Теперь мы - в основном каталоге Сабскрайба!! Теперь мы - ruleZ!! Теперь - Матрице точно 3,1415926Z!! (аминь!)

На следующий же день, кстати, мы тоже замачивали (правда, напиток был на этот раз менее дZенским), а именно - открытие новой версии раздела "Инструметы". Теперь это раздел с психологически правильным названием "Download"... Как сказал бы чуждый советскому обществу психоаналитик Зигмунд Фрейд, "анальная" стадия развития нашего сайта в кои-то веки начала перерастать в "генитальную"...

Почему так? А потому что раньше Матрица имела нас, а теперь... а теперь мы делаем первые робкие попытки поиметь Матрицу!!

И еще: сегодня НАС намного больше, чем вчера!!

ПОЕХАЛИ!!

ПРИШЛО ВРЕМЯ ДЕЛАТЬ ФАК (FAQ - ЧАСТОЗАДАВАЕМЫЕ ВОПРОСЫ И ОТВЕТЫ)

Черти!! Ни одного вопроса "в тему", блин!! Хоть бы один человек попросил пропить ему сигнатуру Матрицы!! Так ведь нет! Все ГЛУПЫЕ вопросы задают какие-то... Да ладно, если бы один такой доходяга был - проигнорировали бы это "чудо", и все... Так ведь нет! Пачками спрашивают!! Хоть провайдеру на этих спамеров жалуйся... ;)

Ну а так как жаловаться провайдеру - еще то западло, приходится чесна (ну... почти) на все отвечать (попробуем):

Вопрос: Почему вы не совсем полно освещаете некоторые вопросы? В классических учебниках по assembler'у тот же порядок загрузки компьютера описан намного подробнее...

Ответ: Утешьте себя тем, что мы собираемся рассматривать ту же "загрузку компьютера" во много раз глубже, чем это рассматривается в ваших любимых "классических учебниках". Белым же по черному написано: ПЕРВОЕ ПОГРУЖЕНИЕ. А будет еще и второе, и третее...

Я не думаю, что вам бы понравилось, если бы первые 20-30 выпусков рассылки были посвящены именно этому, но зато - "досконально" и "подробно"... М-да... в этом случае в выпуске этак 150-м, собрав остатки ваших мозгов, вы бы написали дрожащими руками вашу первую прогу...

Вопрос: Почему мы именно на c:\windows\command\debug.exe все делаем?? Ведь есть более удобные дебуггеры, тот же hiew, например...

Ответ: Отвечу вопросом на вопрос: а нахрена карате учить, если можно с ломиком на танцы ходить??

Просто прежде чем мы коснемся многочисленного инструментария, научимся сначала обходиться БЕЗ него. Чтобы потом НЕ ЗАВИСЕТЬ ни от компилятора, ни от прочих многочисленных утилит... Чтобы не бояться АДРЕСАЦИИ, МАШИННЫХ КОДОВ, РЕГИСТРОВ и прочей дури...

Наш курс аналогичен "школе боевых искусств" (только что осенило!). Прежде чем изучать "навороты", необходимо отшлифовать до автоматизма, до АБСОЛЮТНОЙ ПРАВИЛЬНОСТИ обыкновенный ПРЯМОЙ УДАР. Если не сделать этого ДО всего остального, то какие бы стойки бы вы не принимали, на какие бы высоты не закидывали ваши нижние конечности, любой мало-мальски сильный противник с легкостью докажет вам то, во что вы долго не сможете уверовать - то что вы ламер, а вовсе никакой не каратист...

Вывод? Ломик все равно круче!! Если избегать глубокой воды...

А попробуйте избежать глубокой воды в болоте!!

Вопрос: Ваша рассылка - она что... ХАКЕРСКАЯ???

Ответ: ДОСТАЛИ!! Нет, не хакерская. Я же подписываюсь как? - Serrgio!! Если бы она была хакерской, я бы подписался так: $ERRgIO! Понятно??

(как это никто еще не догадался про мою личную жизнь спросить?!)

ХВАТИТ ЕРУНДУ СПРАШИВАТЬ!!

НОВЕНЬКИМ: СЛЕДУЙТЕ ЗА БЕЛЫМ КРОЛИКОМ (ЭТО ИЗ MATRIX'А, ЕСЛИ ПОМНИТЕ)

Выпуск 2 - про систему счисления.

Выпуск 3 - про порядок загрузки компьютера.

Выпуск 4 - про регистры.

Выпуск 5 - про программу в памяти.

Выпуск 6 - про прерывания.

А ТЕПЕРЬ МЫ ПРОДОЛЖИМ "ПРОГРАММИРОВАТЬ"!!

[1] Тем, кто не в курсе - НАСТОЯТЕЛЬНО рекомендую проштудировать предыдущие выпуски рассылки, иначе въехать будет сложно...

Тем, кто внимательно читал предыдущие выпуски, сегодняшние упражнения для ума и пальцев покажутся детским лепетом...

Давайте немножко видоизменим программу, которую мы писали в прошлый раз. Сделаем так, чтобы наше "окошко скроллинга" было более-менее посередине экрана...

      :0100 XOR AL,AL        ;ПРИМЕЧАНИЕ: с целью экономии пространства-времени
      :0102 MOV BH,10       ;я немножко кастрировал наш DEBUG-овский листинг - 
      :0104 MOV CH,05       ;т. е. убрал адрес сегмента и машинные коды, соответствующие
      :0106 MOV CL,10       ;мнемоническим командам :))
      :0108 MOV DH,10       ;
      :010A MOV DL,3E       ;а так, естесна, в оригинале первая строка вот как выглядеть
      :010C MOV AH,06       ;должна: 11B7:0100 30C0 XOR AL,AL 
      :010E INT 10
      :0110 INT 20

Теперь - задача: нужно написать программу, которая последовательно выводит 5 таких окошек, причем каждое последующее окно "вложено" в предыдущее, а значение атрибута в шестнадцатеричной нотации на 10 больше предыдущего...

Если мы будем программировать ЭТО линейно (именно так для начала), то очевидно, что все, что мы должны сделать - это заданное количество раз (5) заставить машину выполнить вышеуказанные операции, изменяя перед "запуском прерывания" значения регистров AL, BH, CX, DX (полное описание функции 6 10-го прерывания ищите в прошлом выпуске).

[2] Что вы должны были "пораскинуть мозгами"?? А вот что:

Угу... за атрибут (то бишь цвет) у нас отвечает регистр BH. У нас он был равен 10h, а нужно на 10h больше... это, значит, 20h будет...

Ладно... CX (он же CH и CL, как известно) - это ТОЖЕ ШЕСТНАДЦАТЕРИЧНЫЕ координаты левого верхнего угла нашего окошка.

"Угу. Чтоб "окно в окне" получилось, это нужно на строчку больше сделать... хм... и на колонку - тоже больше... и это все тоже - в HEXe считать... Это получается, что в регистр СH нужно вместо 05h значение 06h внести, а в регистр CL вместо 10h - 11h.

А еще одним махом можно - в CX число 0510h. Той же командой mov... Или стоп! Что-то припоминаю на счет "перевернутого" хранения байтов... Хотя... вроде это только памяти касалось... Проверить нужно!! В смысле если в CX одним махом пихать - то что: 0510h или 1005h??"

ПРОВЕРЯЙТЕ, ЧЕРТ ВАС ПОДЕРИ!! ПРОВЕРЯЙТЕ!!

Ладно... DX (DH и DL соответственно) - это координаты правого нижнего угла четырехугольника. DH = 10h - 1h = Fh и DL = 3Eh - 1h = 3Dh.

Ну а AL=0 и AH=6 - это уже и ежу понятно из описания данной функции (mov AH,6) данного прерывания (INT 10h).

Все, что осталось - это набить в debug'е после команды "a" эти мнемоники энное количество раз. 5 вроде...

Набиваем!!

      :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 INT 20              
      :0112 XOR AL,AL        ;второй раз 
      :0114 MOV BH,10 
      :0116 MOV CH,06 
      :0118 MOV CL,11 
      :011A MOV DH,0F 
      :011C MOV DL,3D 
      :011E MOV AH,06 
      :0120 INT 10 
      :0122 INT 20             ;третий раз 
      :0124 XOR AL,AL 
      : и т.д

Правда, карсивые циферки-буковки?? Набиваем-набиваем!! Если сейчас к вам подойдут не дZенствующие приятели/коллеги и посмотрят, что вы тут колупаете, то ничерта не поймут и покрутят пальцем у виска... Привыкаете к этому... Только не говорите им, что пытаетесь сейчас поиметь Матрицу... Потому что это неправда...

А неправда это потому, что сейчас Матрица в очередной раз поимела вас!!

[3] А ПОТОМУ ЧТО МОЗГАМИ ДУМАТЬ НАДО, А НЕ ТОЛЬКО СЛЕПО СЛЕДОВАТЬ РУКОВОДСТВУ!!

У вас только первое окно прорисуется, сразу же после чего программа натолкнется на INT 20h и благополучно завершится!! А следовательно и все, что после первого CD 20 написано будет - останется прогигнорированным!! Исправляйте!!

Второй момент. Это прерывание ВОЗВРАЩАЕТ ЛИ ЧТО НИБУДЬ В РЕГИСТР AX?? Смотрите описание... Ничего?? Ну так какого хрена тогда по новой вводить XOR AL,AL и MOV AH,06?? Переприсваивать AH значение 6h если и без того AH = 6h ?? Один раз ввести - более чем достаточно!!

Скажите, какая мелочь!! Байтом больше, байтом меньше... А я скажу вот что: на то он и assembler, чтобы "байтом меньше"...

Исправляйте!!

[4] "Исправляйте?? - возмутитесь вы - Да это же по-новому все вводить нужно!!"

"По-новому?? - возмутимся мы в свою очередь! - Зачем по-новому? Вы что, с ума сошли??"

1. Что вам мешает после команды "a" указать адрес, который вы желаете переассемблировать? И благополучно заменить старую команду на новую!!

"А что делать, если не переассемблировать нужно, а вообще удалить?"

2. Существует куча способов, что вы в самом-то деле!! Например, в HEX Workshop'е с блоками шестнадцатеричных цифр - запросто можно работать...

Кстати, если процессор встретит команду NOP, то он просто побездельничает некоторое очень короткое время...

ПРОБУЙТЕ!! В конце концов ваша прога должна принять такой вот вид:

      :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 BH,20   ;окошко второе 
      :0112 MOV CH,06 
      :0114 MOV CL,11 
      :0116 MOV DH,0F 
      :0118 MOV DL,3D 
      :011A INT 10 
      :011C MOV BH,30   ;окошко третее
      :011E MOV CH,07 
      :0120 MOV CL,12 
      :0122 MOV DH,0E 
      :0124 MOV DL,3C 
      :0126 INT 10 
      :0128 MOV BH,40   ;окошко четвертое 
      :012A MOV CH,08 
      :012C MOV CL,13 
      :012E MOV DH,0D 
      :0130 MOV DL,3B 
      :0132 INT 10 
      :0134 MOV BH,50   ;окошко пятое 
      :0136 MOV CH,09 
      :0138 MOV CL,14 
      :013A MOV DH,0C 
      :013C MOV DL,3A 
      :013E INT 10 
      :0140 INT 20         ;конец этой тупой проги...

О да!! Получившаяся у вас программа - тупа!! И написана долго и бездарно!! Имейте это ввиду :)).

Торжественно обещаю, что в следующем выпуске мы ее усовершенствуем...

Да вот еще что: особенно извращенные могут попытаться заменить INT 20 на jmp 100... получится, конечно не ахти, но все же - "анимация" типа... СПЕЦДЕФЕКТ!!

[5] А теперь мы попробуем ОТЛАДОЧНЫЙ прием!! Все кракеры его знают и пользуются им для взлома софта. Имейте ввиду: пока вы будете использовать его для своих исполнимых программ - вы программер, исправляющий ошибки; а как только попытаетесь использовать это для отвязки чужой программы от какого-нить серийного номера - вы станете ПРЕСТУПНИКОМ. Так что думайте сами, что лучше - флаг в руки или барабан вместе с петлей на шею...

Итак, вводим приблизительно такую командную строку: debug имя_проги.com или же подгружаем прогу в отладчик командой "l" (от слова load) и трассируем, как вы уже неоднократно это делали...

Цель: "на лету" (без изменения кода) заставить первое окошко "рисоваться" не синим (BH=10h), а красным (BH=40h) цветом.

Я просто приведу вам последовательность действий, а вывод зачем это нужно и прочие возможные выводы вы уже сами делать будете, ок?

     -t 
     AX=0000 BX=0000 CX=0043 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 
     DS=11B7 ES=11B7 SS=11B7 CS=11B7 IP=0102 NV UP EI PL ZR NA PE NC 
     11B7:0102 B710 MOV BH,10
     - 

Состояние: обнулился регистр AX (первую команду MOV AL,AL мы не видим). Процессор готовится выполнить команду MOV BH,10.

Дадим ему это сделать!!

     -t 
     AX=0000 BX=1000 CX=0043 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 
     DS=11B7 ES=11B7 SS=11B7 CS=11B7 IP=0104 NV UP EI PL ZR NA PE NC 
     11B7:0104 B505 MOV CH,05
     -

Состояние: в BX уже внесен код синего цвета, который нам по условию необходимо заменить на красный (т. е. заменить значение регистра BX с 1000h на 4000h).

Вот теперь-то мы и делаем это "на лету":

     -r bx 
     BX 1000 
     :4000 
     - 

А действительно ли сделали??

А проверим!!

     -r 
     AX=0000 BX=4000 CX=0043 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000 
     DS=11B7 ES=11B7 SS=11B7 CS=11B7 IP=0104 NV UP EI PL ZR NA PE NC 
     11B7:0104 B505 MOV CH,05 
     - 

Состояние? BH теперь равно 40h! Мы "вклинились" между строчками:

     
     :0102 MOV BH,10 
     :0104 MOV CH,05 

и изменили текущую цепь событий, заставив программу делать ТО, ЧТО НАМ НУЖНО!!

Поздравляю!!

А дальше - вводим команду "g" и даем нашей тупорылой программе исполниться...

1:0 не в пользу Матрицы!!

дZенствуйте и медитиRуйте, братья!!

и да пребудет с вами Cила!

АНОНС СЛЕДУЮЩЕГО ВЫПУСКА

В следующий раз мы продолжим программировать: на этот раз познакомися с циклами + некоторые сведения об "оптимизации" по размеру и быстроедйствию...

PS: ПРОZЬБА К ЧИТАТЕЛЯМ ЭТОГО БРЕДА

Господа!! Не сочтите за трудность отметиться в нашей ПРИНЦИПИАЛЬНО НЕМОДЕРИРУЕМОЙ Гостевой Книге!!