Погружение в ассемблер. Сокращаем размер программы - «Новости» » Самоучитель CSS
Меню
Наши новости
Учебник CSS

Невозможно отучить людей изучать самые ненужные предметы.

Введение в CSS
Преимущества стилей
Добавления стилей
Типы носителей
Базовый синтаксис
Значения стилевых свойств
Селекторы тегов
Классы
CSS3

Надо знать обо всем понемножку, но все о немногом.

Идентификаторы
Контекстные селекторы
Соседние селекторы
Дочерние селекторы
Селекторы атрибутов
Универсальный селектор
Псевдоклассы
Псевдоэлементы

Кто умеет, тот делает. Кто не умеет, тот учит. Кто не умеет учить - становится деканом. (Т. Мартин)

Группирование
Наследование
Каскадирование
Валидация
Идентификаторы и классы
Написание эффективного кода

Самоучитель CSS

Вёрстка
Изображения
Текст
Цвет
Линии и рамки
Углы
Списки
Ссылки
Дизайны сайтов
Формы
Таблицы
CSS3
HTML5

Новости

Блог для вебмастеров
Новости мира Интернет
Сайтостроение
Ремонт и советы
Все новости

Справочник CSS

Справочник от А до Я
HTML, CSS, JavaScript

Афоризмы

Афоризмы о учёбе
Статьи об афоризмах
Все Афоризмы

Видео Уроки


Видео уроки
Наш опрос



Наши новости

       
20-10-2020, 00:00
Погружение в ассемблер. Сокращаем размер программы - «Новости»
Рейтинг:
Категория: Новости

Пог­ружение в assembler
Де­лаем пер­вые шаги в осво­ении асма
Ос­ваиваем ариф­метичес­кие инс­трук­ции
Как работа­ют перемен­ные, режимы адре­сации, инс­трук­ции условно­го перехо­да
Учим­ся работать с памятью
Ра­бота­ем с боль­шими чис­лами и дела­ем слож­ные матема­тичес­кие вычис­ления

Резьба по ассемблерному коду


На­деюсь, ты зна­ешь кни­гу Сти­вена Леви «Хакеры: герои компь­ютер­ной револю­ции». Если нет, обя­затель­но проч­ти! Сей­час мы с тобой понос­таль­гиру­ем по тем слав­ным вре­менам, которые опи­сыва­ет Леви. В час­тнос­ти, вспом­ним, чем пионе­ры хакерс­тва занима­лись в «Клу­бе модели­рова­ния желез­ной дороги» Мас­сачусет­ско­го тех­нологи­чес­кого инсти­тута и как они кодили.


Ха­керы тех вре­мен, кор­пя над сво­ими прог­рамма­ми, пытались выжать из ассем­блер­ных инс­трук­ций все, что толь­ко воз­можно, что­бы в ито­ге прог­рамма ста­ла мак­сималь­но ком­пак­тной. Попыт­ки отре­зать часть инс­трук­ций от компь­ютер­ной прог­раммы без воз­дей­ствия на конеч­ный резуль­тат ста­ли для хакеров навяз­чивой иде­ей.


Иног­да такая резь­ба по ассем­блер­ному коду при­нима­ла сос­тязатель­ный харак­тер — сво­еоб­разное сорев­нование мачо, приз­ванное доказать себе и дру­гим, что совер­шенс­тву нет пре­дела. Ты отре­зал две инс­трук­ции или даже одну? Получи бур­ные апло­дис­менты брать­ев по духу. Ты перес­мотрел проб­лему с нуля, с неожи­дан­ного угла зре­ния и раз­работал новый алго­ритм, который сок­ратил прог­рамму на целый блок команд? Испы­тай катар­сис и получи еще более бур­ные апло­дис­менты!


Погружение в ассемблер. Сокращаем размер программы - «Новости»

Осо­бое рве­ние хакеры про­явля­ли к опти­миза­ции под­прог­раммы для печати десятич­ных чисел. За нес­коль­ко месяцев они изго­тови­ли целую кучу вари­аций. С чего вдруг такой инте­рес имен­но к этой задаче?


С того, что в MIT дей­ство­вало нег­ласное пра­вило: «Если ты собс­твен­норуч­но написал под­прог­рамму печати десятич­ных чисел, зна­чит, зна­ешь о компь­юте­ре дос­таточ­но, что­бы называть себя в некото­ром роде прог­раммис­том. При­чем, если у тебя ушло на эту под­прог­рамму око­ло сот­ни ассем­блер­ных инс­трук­ций, зна­чит, ты бес­прог­лядный глу­пец, хотя и прог­раммист. А если написал дей­стви­тель­но хорошую и корот­кую про­цеду­ру мень­шего раз­мера, то можешь поп­робовать называть себя хакером».


В конеч­ном сче­те, попере­мен­но уби­рая инс­трук­ции то в одном, то в дру­гом мес­те, хакеры допили­ли про­цеду­ру печати десятич­ных чисел до пятиде­сяти с неболь­шим инс­трук­ций.


Даль­ше дело при­няло серь­езный обо­рот. Поиск луч­шего решения прев­ратил­ся в неч­то боль­шее, чем прос­то сос­тязание, — в поиск свя­того Гра­аля. Одна­ко, сколь­ко бы сил ни было пот­рачено, никому не уда­валось пре­одо­леть барь­ер из пятиде­сяти команд. И ког­да прак­тичес­ки все уже сми­рились с тем, что это невоз­можно, один из хакеров догадал­ся пос­мотреть на решение задачи под дру­гим углом. В ито­ге его вер­сия под­прог­раммы умес­тилась в 46 ассем­блер­ных инс­трук­ций.


До это­го зна­мена­тель­ного часа все счи­тали, что опти­маль­ный алго­ритм для под­прог­раммы печати десятич­ных чисел — это пос­ледова­тель­ное вычита­ние, при котором исполь­зовались таб­лицы сте­пеней чис­ла 10. Одна­ко, как ока­залось, задачу мож­но решить и без такой таб­лицы. Леви, к сожале­нию, не при­водит ассем­блер­ный код в сво­ей кни­ге, поэто­му поз­накомить­ся с этим шедев­ром у нас не получит­ся.


Но не спе­ши расс­тра­ивать­ся. Сей­час я покажу тебе свою вер­сию такой под­прог­раммы. Она у меня умес­тилась в 12 инс­трук­ций (и 23 бай­та).


Ко­му-то может показать­ся, что столь­ко замора­чивать­ся ради того, что­бы сок­ратить раз­мер прог­раммы, в наши дни уже не име­ет смыс­ла. Одна­ко такой навык очень при­гож­дает­ся, ког­да пишешь какой-нибудь шелл-код или редак­тиру­ешь ском­пилиро­ван­ный бинар­ник. И в том и в дру­гом слу­чае нуж­но уметь обхо­дить­ся как мож­но мень­шим количес­твом ассем­блер­ных инс­трук­ций. И сей­час я покажу нес­коль­ко трю­ков, которые помогут тебе сок­ращать раз­мер сво­их ассем­блер­ных прог­рамм.


Читаем данные из памяти по-новому


Во всех пре­дыду­щих уро­ках мы читали память, ссы­лаясь на нуж­ную нам ячей­ку через регистр BX. При­мер­но вот так.


Но то же самое мож­но сде­лать и вот так.


Инс­трук­ция lodsb говорит про­цес­сору 8088: «Заг­рузи байт из адре­са, на который ука­зыва­ет DS:SI, и сох­рани этот байт в регистр AL. И затем уве­личь SI на еди­ницу (если флаг нап­равле­ния сбро­шен в 0)».


Еще у 8088 есть инс­трук­ция lodsw, которая работа­ет поч­ти как lodsb, толь­ко заг­ружа­ет из DS:SI сло­во (сдво­енный байт), сох­раня­ет резуль­тат в регистр AX и уве­личи­вает SI на 2.


Копируем данные, не используя циклы


Зная о сущес­тво­вании инс­трук­ций lodsb/lodsw и их про­тиво­полож­ностей stosb/stows, мы можем написать под­прог­рамму для копиро­вания области памяти.


Этот внут­ренний цикл занима­ет все­го четыре бай­та. Но у про­цес­сора 8088 есть инс­трук­ции movsb и movsw, которые дела­ют ту же самую опе­рацию, но при этом не исполь­зуют регистр AL или AX.


Те­перь внут­ренний цикл занима­ет три бай­та. Но и это не пре­дел! Мы можем сде­лать все то же самое без инс­трук­ции loop.


Об­рати вни­мание, что movsb — это две инс­трук­ции в одной: lodsb и stosb. И ана­логич­но в movsw ском­биниро­ваны lodsw и stosw. При этом movsb/movsw не исполь­зуют регис­тры AL/AX, что весь­ма при­ятно.


Пог­ружение в assembler Де­лаем пер­вые шаги в осво­ении асма Ос­ваиваем ариф­метичес­кие инс­трук­ции Как работа­ют перемен­ные, режимы адре­сации, инс­трук­ции условно­го перехо­да Учим­ся работать с памятью Ра­бота­ем с боль­шими чис­лами и дела­ем слож­ные матема­тичес­кие вычис­ления Резьба по ассемблерному коду На­деюсь, ты зна­ешь кни­гу Сти­вена Леви «Хакеры: герои компь­ютер­ной револю­ции». Если нет, обя­затель­но проч­ти! Сей­час мы с тобой понос­таль­гиру­ем по тем слав­ным вре­менам, которые опи­сыва­ет Леви. В час­тнос­ти, вспом­ним, чем пионе­ры хакерс­тва занима­лись в «Клу­бе модели­рова­ния желез­ной дороги» Мас­сачусет­ско­го тех­нологи­чес­кого инсти­тута и как они кодили. Ха­керы тех вре­мен, кор­пя над сво­ими прог­рамма­ми, пытались выжать из ассем­блер­ных инс­трук­ций все, что толь­ко воз­можно, что­бы в ито­ге прог­рамма ста­ла мак­сималь­но ком­пак­тной. Попыт­ки отре­зать часть инс­трук­ций от компь­ютер­ной прог­раммы без воз­дей­ствия на конеч­ный резуль­тат ста­ли для хакеров навяз­чивой иде­ей. Иног­да такая резь­ба по ассем­блер­ному коду при­нима­ла сос­тязатель­ный харак­тер — сво­еоб­разное сорев­нование мачо, приз­ванное доказать себе и дру­гим, что совер­шенс­тву нет пре­дела. Ты отре­зал две инс­трук­ции или даже одну? Получи бур­ные апло­дис­менты брать­ев по духу. Ты перес­мотрел проб­лему с нуля, с неожи­дан­ного угла зре­ния и раз­работал новый алго­ритм, который сок­ратил прог­рамму на целый блок команд? Испы­тай катар­сис и получи еще более бур­ные апло­дис­менты! Осо­бое рве­ние хакеры про­явля­ли к опти­миза­ции под­прог­раммы для печати десятич­ных чисел. За нес­коль­ко месяцев они изго­тови­ли целую кучу вари­аций. С чего вдруг такой инте­рес имен­но к этой задаче? С того, что в MIT дей­ство­вало нег­ласное пра­вило: «Если ты собс­твен­норуч­но написал под­прог­рамму печати десятич­ных чисел, зна­чит, зна­ешь о компь­юте­ре дос­таточ­но, что­бы называть себя в некото­ром роде прог­раммис­том. При­чем, если у тебя ушло на эту под­прог­рамму око­ло сот­ни ассем­блер­ных инс­трук­ций, зна­чит, ты бес­прог­лядный глу­пец, хотя и прог­раммист. А если написал дей­стви­тель­но хорошую и корот­кую про­цеду­ру мень­шего раз­мера, то можешь поп­робовать называть себя хакером». В конеч­ном сче­те, попере­мен­но уби­рая инс­трук­ции то в одном, то в дру­гом мес­те, хакеры допили­ли про­цеду­ру печати десятич­ных чисел до пятиде­сяти с неболь­шим инс­трук­ций. Даль­ше дело при­няло серь­езный обо­рот. Поиск луч­шего решения прев­ратил­ся в неч­то боль­шее, чем прос­то сос­тязание, — в поиск свя­того Гра­аля. Одна­ко, сколь­ко бы сил ни было пот­рачено, никому не уда­валось пре­одо­леть барь­ер из пятиде­сяти команд. И ког­да прак­тичес­ки все уже сми­рились с тем, что это невоз­можно, один из хакеров догадал­ся пос­мотреть на решение задачи под дру­гим углом. В ито­ге его вер­сия под­прог­раммы умес­тилась в 46 ассем­блер­ных инс­трук­ций. До это­го зна­мена­тель­ного часа все счи­тали, что опти­маль­ный алго­ритм для под­прог­раммы печати десятич­ных чисел — это пос­ледова­тель­ное вычита­ние, при котором исполь­зовались таб­лицы сте­пеней чис­ла 10. Одна­ко, как ока­залось, задачу мож­но решить и без такой таб­лицы. Леви, к сожале­нию, не при­водит ассем­блер­ный код в сво­ей кни­ге, поэто­му поз­накомить­ся с этим шедев­ром у нас не получит­ся. Но не спе­ши расс­тра­ивать­ся. Сей­час я покажу тебе свою вер­сию такой под­прог­раммы. Она у меня умес­тилась в 12 инс­трук­ций (и 23 бай­та). Ко­му-то может показать­ся, что столь­ко замора­чивать­ся ради того, что­бы сок­ратить раз­мер прог­раммы, в наши дни уже не име­ет смыс­ла. Одна­ко такой навык очень при­гож­дает­ся, ког­да пишешь какой-нибудь шелл-код или редак­тиру­ешь ском­пилиро­ван­ный бинар­ник. И в том и в дру­гом слу­чае нуж­но уметь обхо­дить­ся как мож­но мень­шим количес­твом ассем­блер­ных инс­трук­ций. И сей­час я покажу нес­коль­ко трю­ков, которые помогут тебе сок­ращать раз­мер сво­их ассем­блер­ных прог­рамм. Читаем данные из памяти по-новому Во всех пре­дыду­щих уро­ках мы читали память, ссы­лаясь на нуж­ную нам ячей­ку через регистр BX. При­мер­но вот так. Но то же самое мож­но сде­лать и вот так. Инс­трук­ция lodsb говорит про­цес­сору 8088: «Заг­рузи байт из адре­са, на который ука­зыва­ет DS:SI, и сох­рани этот байт в регистр AL. И затем уве­личь SI на еди­ницу (если флаг нап­равле­ния сбро­шен в 0)». Еще у 8088 есть инс­трук­ция lodsw, которая работа­ет поч­ти как lodsb, толь­ко заг­ружа­ет из DS:SI сло­во (сдво­енный байт), сох­раня­ет резуль­тат в регистр AX и уве­личи­вает SI на 2. Копируем данные, не используя циклы Зная о сущес­тво­вании инс­трук­ций lodsb/lodsw и их про­тиво­полож­ностей stosb/stows, мы можем написать под­прог­рамму для копиро­вания области памяти. Этот внут­ренний цикл занима­ет все­го четыре бай­та. Но у про­цес­сора 8088 есть инс­трук­ции movsb и movsw, которые дела­ют ту же самую опе­рацию, но при этом не исполь­зуют регистр AL или AX. Те­перь внут­ренний цикл занима­ет три бай­та. Но и это не пре­дел! Мы можем сде­лать все то же самое без инс­трук­ции loop. Об­рати вни­мание, что movsb — это две инс­трук­ции в одной: lodsb и stosb. И ана­логич­но в movsw ском­биниро­ваны lodsw и stosw. При этом movsb/movsw не исполь­зуют регис­тры AL/AX, что весь­ма при­ятно.

Теги: CSS

Просмотров: 712
Комментариев: 0:   20-10-2020, 00:00
Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь. Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

 
Еще новости по теме:



Другие новости по теме:
Комментарии для сайта Cackle