Вступление
|
||||||||||||||||||||||||||||||||||
Новости сайта28.02.03] В раздел Документация добавлена книга "Дорога в будущее" автор Б.Гейтс В этой книге великий и ужастный Билл Гейтс делится своим видением того, что ждет нас в скором времени. Он раскрывает перед читателем свое видение будущего, рассказывает об основах информатики, развитии мировой компьютерной индустрии, о влиянии вычислительной техники на все стороны жизни общества, в том числе на бизнес и образование.-довольно интересная книжка, сам недавно прочитал. рекомендую. Заодно, если вы не поняли про двоичную систему счисления, прочитаете объяснения самого Гейтса на лампочках :) | ||||||||||||||||||||||||||||||||||
ТеорияВ прошлый раз мы остановились на регистре флажков. Это регистр содержит такие флаги (* - не используемые биты):
cmp bx, 00Как же узнать какой флаг установился, а какой нет? Для этого есть команды для перехода на метку, если флаг установлен. Всех их писать я не буду. Но например, если в предыдущем примере BX = 0, тогда сравнение вызовет установку флага ZF (Zero Flag - флаг нуля). Команда jz вызывает переход на метку, если установлен ZF. Для нашего примера: cmp bx, 00Во встроенном ассемблере могут использоваться три предопределённых имени:
Обратим взгляд на неизвестную нам команду jl - переход если меньше. Т.е. в нашем случае если AX меньше Y, то совершается переход на метку @less. Кстати откуда такое странное название (начинается с @)? Это так называемые локальные метки - метки в которые можно передать управление только внутри ассемблерной вставки. Т.е. вы не можете прыгнуть на неё с помощью goto. С другой стороны нам не надо объявлять такую метку в разделе label, так что начинайте свои метки с символа @. Этот символ говорит компилятору, о том что метка локальная.Так вот значит, если AX меньше Y (т.е. если X меньше Y), тогда мы переходим на метку @less. И записываем в @Result значение АХ (а там у нас Х). Если же Y меньше Х, тогда переход на метку не состоится и мы сначала занесём в АХ Y, а потом значение АХ в @Result. Вот таким образом компилятор преобразовывает наши высоко уровневые конструкции if-else к машинным cmp. Естесственно в силу превосходства человека над машиной, наш код меньше, чем генерируемый компилятором. Однако давайте обратим свой взор на использование функций процедур, написанных на ассемблере. Во перых объявление таких подпрограмм должно идти с директивой assembler. Во вторых исполняемая чать вместо привычного begin - end обрамляется asm - end. Т.е. шаблон выглядит так:
При этом ассемблерные функции должны возвращать свои значения следующим образом:
так как мы возвращаем значение типа integer, то нам надо запихать это значение в АХ (что мы и делаем). Обратите внимание, что наш код сократился ещё на одну строку. Нам не надо записывать возвращаемоео значение в @Result. Метка @less теперь у нас соответствует выходу из подпрограммы.Следующие строки будут целиком понятны только для людей знакомых с ассемблером более чем поверхностно. Однако и вам полезно это знать. Итак на входе и выходе в ассемблерную подпрограмму генерируется следующий код (он добавляется в ехе файл): Если входные и выходные параметры отсутствуют, то создаётся код содержащий единственную инструкцию ret. Как я уже когда-то писал все параметры передаются в подпрограммы черз стек. Так же все локальные переменные хранятся в стеке. Поэтому при входе в процедуру создается локальный стек: в bp помещается текущая граница стека, а сама эта граница сдвигается на суммарную длинну всех локальных переменных что бы работа со стеком не разрушила локальные переменные. Например:
Как я написал выше, результат функции других вещественных чисел возвращается в регистре ST (0) сопроцессора. Что же такое сопроцессор?Как следует из названия это "дополнительный" процессор. Сопроцессор - это процессор для работы с числами с плавающей запятой. Вообще-то полное название - арифметический сопроцессор. Этот сопроцессор имеет свою систему команд разработанную специально для ускорения математических расчётов. Раньше не все компьютеры были оснащены сопроцессором. Сейчас он неизменно присутствует на всех машинах. Поэтому компилятор Турбо Паскаля содержит 2 режима компиляции с поддержкой сопроцессора : Options->Compiler раздел Numeric processing. Галочка у 8087/80287 - при компиляции будут использованы команды сопроцессора. Галочка у Emulation - будет использован режим эмуляции. Т.е. при компиляции будет эмулироваться сопроцессор. Помимо арифметического сопроцессора существует куча сопроцессоров. Самый яркий пример - графический, для ускорения работы с графикой (он содержит в себе функции для рисования графических примитивов). |
||||||||||||||||||||||||||||||||||
Кул-][ацкерамХотите почувствовать себя героем фильма Матрица и иже с ними? Нет ничего проще! Правда во времена создания BP никто о существовании Матрицы не подозревал, но такую возможность предоставили. Итак возьмём простенькую програмульку из прошлого выпуска:
сохраняем, делаем ехе файл и выходим из Паскаля.теперь запускаем bp\bin\td.exe - это Turbo Debugger. Отладчик фирмы Borland. Выбираете File->Change Dir В появившемся окне вводите путь к программе (без имени!). Помните, что путь должен быть короче 8 символов (имеется ввиду длинна имени каждой папки). Если сразу затрудняетесь, то введите только имя диска, на котором находится ехе файл. Дальше File->Open и выбираем нужный нам ехе файл (видите именно ехе, а не pas). На все появшиеся сообщения (если такие будут) ответьте Ок. Окно у вас должно представлять собой нечто такое:
Нечто похожее показывают во всех фильмах о компьютерах. Итак что мы имеем. Сейчас я вам проведу обзорную экскурсию. Большую часть окна (вверху слева) занимает наша программа. Как, а где begin, где end? Я этого не писал ! - такие мысли наверняка уже посетили вас. Скажу сразу. Это машинный код нашей программы переделанный в "понятные" нам команды ассемблера. Вот в это и преобразовывает наши прекрасные программы компилятор. Чуть правее вы видите уже знакомые нам имена регистров. Ну и в самую правую часть окна выведен регист флажков по битам (выведены сответственно имена битов и их состояние). Под кодом программы распологается дамп сегмента данных. Процитирую в очередной раз Serrgio "Картинка", которую вы увидели, называется "дамп памяти" (что в переводе с английского означает "свалка") и она насыщена не только важной информацией, но и специальной низкоуровневой энергетикой. Да чего уж там греха таить - каждый ассемблерщик знает, что рассматривание дампа памяти поднимает настроение, жизненный тонус и другие, не менее важные вещи ;)Так что поднимайте ваш жизненный тонус и отправимся изучать подробнее этот дамп. Итак слева как можно догадаться адресс (вернее только смещение, т.к. сегмент задаётся DS). В центре идут hex числа, справа их расшифровка в коды символов. Так например первый байт по адресу DS:0000 имеет значение5 CDh, а символ с номером CD это = (равно). Следующий за ним байт со значением 20h - это пробел и т.д. Последнюю часть окна мы пока трогать не будем. Теперь давайте посмотрим как вставился наш ассемблерный код ... ищем в коде программы jmp @next.... как вы не нашли ? Правильно. Ведь при компиляции имена меток заменяются адресами. Так что мы пойдём другим путём. Итак давим до боли знакомую клавишу F8 (нам надо именно Step Over, так что именно F8 иначе можете оказаться где-то в месте далёком от нашего кода :) Обратите внимание: зажглись регистры - только, те которые измениись. Это запустилась наша программа. Итак мы дошли до места похоже на то, что мы писали ? но ведь текст начинался с jmp @next, где же он? Давайте рассмотрим текущую строчку: вначале идёт смещение текущей команды относительно сегмента кода (посмотрите кстати на регистр ip). Дальше идёт цифра означающая код команды в hex виде. Т.е. для команды push ds это 1E. Ну и дальше идёт соответственно команда ассемблера. Итак нам надо искать jmp, который ссылается на строчку с адресом 001E - ведь именно её мы пометили меткой @next. Такой jmp находится по адресу cs:000F - jmp 001E - это и есть наш jmp @nextcs:001E 1E push ds Теперь смотрите на строку mov dx, offset @msg- эта строка скомпилировалась в mov dx, 0011 - 'эта адрес строки в сегменте кода, на который у нас ссылается ds. Выберете View -> Dump и посмотрите на дамп - там и правда будет строка Hello World! Теперь обратим взгляд на код нашей програмки именно с адреса 0011 - там находятся команды, которые мы перепрыгнули - а ведь, это то, во что скомпилировался наш Hello World!. А именно в это: такие вот дела. Ну что именно с помощью вот такого простого изучения кода и орудуют взлощики программ. Естественно средства у них более разнообразные и современные. Теперь, когда к вам придут друзья можете запутить td и смотреть на их расширяющиеся от удивления глаза :)dec ax insb gs: insb outsw and [bx+6F],dh jb 0087 and fs:[si],sp |
||||||||||||||||||||||||||||||||||
Это должен посетить каждый!
|