Асемблер Це просто! Вчимося програмувати Випуск N 012 (bler) Розсилка

За останні 60 днів5 випусків (2-3 рази на місяць)

Сайт розсилки: http://rusfaq.ru Відкрито: 28-06-2000

Статистика

Асемблер? Це просто! Вчимося програмувати Випуск N 012

Здрастуйте, здравствуйте, дорогі мої!

Випуск N 012

Квасу. Знову квасу ковток хліба.

Знаю, що розсилку зараз отримаю.

Потрібно якнайшвидше мені до мережі лише увійти.

Щоб там новий випуск знайти.

Де ж ти моя, довгоочікувана, де?

Слини течуть уже по бороді.

Ось ти! Ща тебе я прочитаю.

Що в нас сьогодні?

http://www.oleg77.newmail.ru (тут також можна знайти все необхідне програмне забезпечення для роботи з асемблером).

Якщо у Вас немає доступу до мережі, то напишіть мені лист із проханням надіслати той чи інший випуск або всі разом:

Друзі мої! У нас суттєво змінився зовнішній вигляд сайту. У цьому мені допоміг BoB, за що йому велике спасибі, а також море подяки.

Тепер там є Гостьова книга, де ви можете особисто залишити своє враження, побажання, критику та інше.

З'явився також розділ листів, які ви можете надсилати самі на сайт (наприклад, рішення програми, думки, нотатки та інше).

Єдина проблема: закачати всю цю справу на сайт www.oleg77.newmail.ru. Думаю, що цього тижня я все зроблю.

Якщо вам цікаво, то можете пізніше подивитися одним оком. Всі ваші відгуки приймаються тут: [email protected]? Subject = Сайт

Я вже не раз писав, що до мене дуже багато надходить листів. Якби за добу було 124 години, то я, можливо, зміг би всім відповісти. Я перепрошую, якщо хтось не отримав відповіді. У мене справді немає часу відповідати на всі листи.

Отже,у першу чергу я відповідаю на листи:

  • з проханням надіслати попередні випуски розсилки;
  • з проханням вислати shell.asm, virus.asm, resident.asm та інші програми на асемблері, які необхідні для роботи;
  • з проханням надіслати програмне забезпечення (masm, afd, hiew тощо).

У другу чергу я відповідаю на такі листи:

  • "написав програму з випуску Х, а вона не працює. Я робив так і так, у мене такий комп'ютер (386, Pentium.), такий асемблер (MASM, TASM версії х.хх), така ОС (MS-DOS, Windows 95/98). Набрану мною програму додаю. Знайдіть і виправте мої помилки."
  • "Не працює MASM (TASM, AFD, HIEW). Пише те й те. Я запускаю його так і так. Що робити?"

Я не відповідаю на листи такого плану:

  • "Я сам тракторист. В очі комп'ютер ніколи не бачив. Тиждень тому мені дістався у спадок від прабабусі Pentium-III 800. Будь ласка, напишіть докладно, що потрібно зробити, щоб він заробив (які дроти кудись повтикати, яку кнопку натиснути, які програми встановити) та ін.) Прошу також вислати на e-mail моєму другу ВСІ необхідне програмне забезпечення (Windows 2000, MS Office 2000 та інше.) З повагою, Ізя АбдулаєвP.S. головне - як його вставити в комп'ютер? У мого діда є один, але він ходить з ним на полювання кожен день і мені не дає.
  • "Я підписався на вашу розсилку недавно. Одна біда: ніколи не працював з DOS. Напишіть докладно, як мені завантажити Norton Commander (DOS Navigator), як у ньому створювати та видаляти файли, як їх редагувати. І взагалі, що таке командний рядок?" З повагою, учень 3-го класу Чайников Т."
  • "Я пишу програму з управління супутниками. Будь ласка, напишіть мені процедуру, яка виводила б супутник на орбіту. А то щось у мене нічого не виходить. З повагою, космонавт Невесомов."
  • "Здорово, брате! Допоможи мені хакнути банк "Кідалово". Хочу перевести бабки одного мужика на свій рахунок. Чекаю на відповідь! Вован Безбазаров."

Подібні листи надходять пачками. Я просто фізично не можу відповісти на все. Ще не забувайте, що в мене робота, навчання, син та купа проблем. Будь ласка, не ображайтеся, якщо я комусь не відповім.

Ще один момент. Т.к. я користуюся безкоштовними скриньками (beep.ru, hotmail.ru), які не несуть відповідальності за послуги, то, можливо, що ваш лист не дійде до мене. Якщо я не відповім протягом 3 днів, то надішліть його повторно, будь ласка.

"Вішліть мені стольник і отримайте лимон!"

"Всі ви козли, а я - Д'Артаньян!"

"Подивися мої фотки в прокладенні!"

"Пропоную круту роботу за шалені гроші! Подробиці в додатку."

та інше. Я таких листів не надсилаю та їх не читаю, чого і вам раджу. Якщо ж до вас прийшов подібний лист від мого імені, то, будь ласка, повідомите мені про це. Буду дуже вдячний.

Я отримав листа від одного з передплатників позаминулого тижня, який вказав на помилку у випуску N 009 (коли читали самі себе на згадку). Ех, яку я припустився прикру логічну помилку! А помітив лише один передплатник, який мені довго пояснював її суть. Ай-так, молодець, Сергію! Отже, ось він, це лист:

Здрастуйте, Олеже! Вибачте за настирливість, але.

Боюся, що я не дуже правильно порушив питання. Спробую спочатку.

Thursday, October 05, 2000, 1:24:51 PM, you wrote:

КО> Open_File proc

КО> cmp Handle, 0FFFFh ;Якщо в Hanlde не 0FFFFh (див. нижче), то знову відкривати не треба. КО> jne Quit_open КО> mov ax, 3D00h; відкриваємо на читання КО> int 21h КО> mov Handle, ax; рятуємо handle

КО> Тепер Handle у нас не 0FFFFh. Тому, якщо ми спробуємо закрити файл, то перш за все перевіримо, чи відкритий він був (чи рівно Handle 0FFFFh; якщо так, то закривати нічого.) Згоден. Важко не погодитись.

КО> Ось тут перевіряємо, чи містить Handle 0FFFFh. Тобто. викрито чи файл насправді чи ні. Так, але між викликами процедури open_file і close_file ми перечитуємо файл і це і змінює handle! А саме, на мою думку, події відбуваються так Дія Handle (після) -------------------------- ------------------------- початок FFFF open_file 1 (не важливо що, головне що не FFFF) читання файлу FFFF! Ось про це я і кажу! нижче close_file FFFF

Спробуйте замінити процедуру закриття на наступну (просто додати висновок 2х рядків) - те, що я додав праворуч позначено ';///':

Close_File proc cmp Handle, 0FFFFh je No_Close mov ah, 3Eh mov bx, Handle int 21h mov Handle, 0FFFFh mov ah, 9h ;/// / mov dx, offset Mess_Close_ok ;/// int 21h ;/// No_Close: mov ah, 9h ;/// mov dx, offset Mess_Close_Nok ;//// int 21h ;/// ret Close_File endp

Якщо все працює нормально (як Ви кажете) то спочатку виводиться рядок Mess_Close_ok, а потім Mess_Close_Nok. Але реально рядок Mess_Close_ok не виводиться (а начебто має бути, коли Handle не FFFF)!! А виводиться одразу Mess_Close_Nok

Тобто маємо - команда 'je No_Close' у цій процедурі виконується та йде на мітку No_Close. Про всяк випадок я доклав asm-файлик(чи мало Ви стерли цей приклад, та й щоб не правити руками), де процедура закриття саме така і цей ефект можна спостерігати.

Саме про цей ефект я й казав. Адже після відкриття файлу Handle точно не FFFF (принаймні в дебаггері). А ось перед закриттям – FFFF. Тобто залишається припустити, що коли ми перечитуємо файл, Handle стає FFFF. Чому так – я намагався описати раніше.

Best regards, Sergey

Ось ще одна пропозиція:

На мою вона в 2 рази краща за Жордейна. Я свого часу на ній навчався.

Ну і ще один лист. Потрібна допомога одному з наших передплатників. Може, хтось підкаже чого:

Тепер до діла.

Сьогодні розглянемо один із варіантів застосування резидента. Спочатку подивіться файли resid12.asm та test12.asm.

Що робить програма? Спочатку завантажимо файл resid12.com на згадку. Потім запустимо файл test12.com. Що ми бачимо?

Resid12.com залишає у пам'яті процедуру, яка виводить на екран рядок ASCIIZ (рядок, що закінчується символом 0). Причому процедура Int_10h_proc "вішується" на 10h переривання (це переривання BIOS (ПЗУ), як ви вже знаєте). Щось схоже ми розглядали позаминулого випуску. В даному випадку ми як би додаємо ще одну функцію (88h) до переривання 10h. Для того, щоб вона відпрацювала, нам потрібно викликати 10h переривання, а регістри завантажити необхідні числа (дані). Це:

AH=88h – номер нашої функції;

Зверніть увагу, що ми в DS (сегмент) нічого не завантажуємо, тільки в SI (зміщення). Якщо ви забули, то нагадаю: при старті будь-якого *.com-файлу, сегментні регістри CS, DS, ES, SS дорівнюють нашому єдиному сегменту, в який завантажилася програма. Сегмент може бути будь-яким. Все залежить від того, скільки резидентних програм завантажено.

Отже, детально розглянемо програму resid12.asm.

Спочатку переходимо на мітку ініціалізації. При ініціалізації зазвичай налаштовуються необхідні регістри, перехоплюються переривання тощо. відбувається "підготовчий процес".

Насамперед перевіримо, чи завантажено наш резидент на згадку чи ні. Як це робиться? Т.к. ми перехопили переривання, то можемо з нього зробити відгук. Ось ми й робимо. Викликаємо 10h переривання, занісши в регістр AX "магічне число": 8899h (можна будь-яке інше. Головне - щоб не конфліктувало з якоюсь функцією цього переривання). Зрозуміло, що AH заноситься 88h, а AL - 99h. Функції 88h у 10h переривання немає (не дійшли поки розробники цього числа). Це можна упевнено припустити на 99,9%. Т.к. такої функції не існує, то станеться негайний вихід з 10h переривання(реєстри не змінюються!), що легко перевірити у відладчику. Отже, викликавши 10h переривання з числом 8899h в AX і отримавши у відповідь 8899h у тому AX, ми впевнені, що наш резидент ще не завантажений. Нині все буде зрозуміло.

Якщо ми вже перебуваємо в пам'яті, перехопивши 10h переривання, то перш за все перевіримо, чи викликають його з числом 8899h в AX. Якщо так, то потрібно буде надіслати якусь відповідь. Який? У нашому прикладі ми міняємо місцями вміст регістрів AH та AL і негайно виходимо з переривання. Простіше кажучи, повертаючись у нашу програму, яка в свою чергу перевіряє, чи повернулося число 8899h або 9988h (пам'ятаєте, якщо нашого резидента немає в пам'яті, то повернеться 8899h в AX. BIOS регістри не змінить, оскільки такої функції просто немає !). Якщо ж повернулося 9988h, то ми в пам'яті! Тобто. шматочок нашої процедури Int_10h_proc поміняв місцями регістри (а хто ще може це зробити?). Дивіться перші рядкипроцедури (частина нашого резидента):

pushf; збережемо прапори

cmp ax,8899h ;перевіримо на "магічне число"

jne Next_test ;якщо не воно, то працюємо далі