Kalashnikoff.ru - Ассемблер? Это просто!.. (Выпуск № 029) (Запуск программ) Ассемблер? Это просто! Учимся программировать

______________________________________

Выпуск N 029 (Запуск программ)

Приветствую вас, уважаемые подписчики!

Сегодня в номере:

Информация для новых подписчиков

Новости

Ваши письма

Запуск программ

Наши партнеры

Информация для новых подписчиков Благодарю Вас, что подписались на рассылку "Ассемблер? Это просто! Учимся программировать". Надеюсь, что Вы не останетесь равнодушны к ней и почерпнете море полезной информации, а также повысите свой уровень в "общении" с IBM-совместимыми компьютерами.

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

Все, что нужно для изучения Ассемблера (предыдущие выпуски, необходимые программы, документацию, форму для подачи вопроса экспертам, а также многое другое), можно найти на сайте http://www.Kalashnikoff.ru. Рекомендую Вам сперва ознакомиться с разделом "Для новых подписчиков".

Если у Вас нет выхода в Сеть, то предыдущие выпуски рассылки, файлы-приложения и информацию для новеньких можно получить по почте, направив пустое письмо по адресу AssmIssues@Kalashnikoff.ru. Архив (420 Кб) будет выслан Вам автоматически в течение двух рабочих дней с момента получения Вашего письма. Однако, пожалуйста, не злоупотребляйте этим, т. к. высылка писем подобного объема несет существенную нагрузку на почтовые сервера. Обращаю также Ваше внимание на тот факт, что бесплатные сервера (mail.ru, beep.ru, newmail. ru и т.п.) не всегда работают корректно. Если письмо к Вам не придет в указанный выше период, то попробуйте отправить запрос еще раз.

Новости 1. Начала работать рассылка "Ассемблер? Это просто! Учимся программировать (FAQ)". Честно говоря, даже не думал, что вопросов будет так много, да и вовсе не ожидал, что эксперты будут так оперативно давать ответы. Очередной раз выражаю благодарность ВСЕМ экспертам, а также подписчикам, задающим вопросы.

____________

2. Сайт переехал на новую хостинговую платформу Majordomo.ru, в связи с чем были небольшие перебои в работе сайта, за что приношу свои извинения (об этом я старался заранее сообщать на головной странице сайта).

Для чего нужно было переходить к новому хостеру?

Плюсы очевидны:

1. Теперь я могу обрабатывать почту Перлом, что позволит экспертам и подписчикам, задающим вопросы, отправлять их (вопросы / ответы) по почте, не заходя на сайт. Осталось дело "за малым": написать программу обработки поступающих вопросов / ответов.

2. Существенно увеличен размер почтового ящика (до 75 Мб).

3. Возможность использования crontab (если правильно пишу). Это такая штука, которая позволяет запускать какую-нибудь программу на Перле в определенное время. Очень удобно, например, для обновления базы данных; высылки предыдущих выпусков (скажем, каждые 30 минут проверять ящик и высылать письма. Для этого мне необязательно сидеть в Сети и пользоваться The Bat!) и пр.

4. Возможность создания поддоменов (доменов третьего уровня). Кстати, новый адрес форума теперь такой: http://forum.kalashnikoff.ru. Вскоре планирую полностью разделить программирование и законодательство.

5. Использование MySQL. Правда, пока толком не разобрался что это вообще такое, но, думаю, со временем научусь всему (говорят, что MySQL - это программа для создания баз данных. Если так, то экспертные группы будут работать гораздо быстрее. Нужно только время...).

В общем, еще дополнительно много чего нового.

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

____________

3. Открыты еще две рассылки:

1. "От Советского Информбюро" (state.politics.discussion):

В рассылке рассматриваются различные точки зрения по поводу развала СССР, объединения СНГ, политики НАТО, действий президентов различных стран, способы возрождения России и стран СНГ, Союзный Договор между Россией и Беларусью и пр. Кроме этого, обсуждения и воспоминания прежних советских времен, плюсы и минусы, ностальгия по прошлому (или наоборот), проблемы современной молодежи и многое другое...

2. "Было время... Был я ламмер..." (rest.joke.lammer):

Реальные юморные истории, анекдоты, рассказы, шутки и многое другое от Настоящих Ассемблерщиков!

Подписаться можно в приведенной ниже форме:

Рассылки Subscribe.Ru От Cоветского Информбюро

Было время... Был я ламмер... Ассемблер? Это просто! Учимся программировать (FAQ)

HTML TEXT SMS PALM windows КОИ-8 Латиница Первый выпуск рассылки "Было время... Был я ламмер..." уже готов и выйдет в самое ближайшее время, где я расскажу свою историю знакомства с компьютерами, Ассемблером, студенческие годы и пр.

Надеюсь, что рассылки будут интересны вам!

Ваши письма Олег, у меня к тебе есть небольшое предложение.

Давай как-нибудь займемся написанием собственной операционной системы, а? Писать под "окна", конечно, интересно, но в них столько "БАГОВ"... Давай что-нибудь СВОЕ сделаем, нас ведь много... Что-нибудь типа Линукса (в смысле свободного кода)... Интересно ведь...

Давай просто еще раз проведем голосование... А?

__________

С удовольствием! Если это заинтересует соответствующее количество подписчиков, то будем делать рассылку. Жду письма от заинтересованных лиц: OS@Kalashnikoff.ru.

Запуск программ  

4BH(1).asm

; 4Bh(1).ASM - программа к рассылке № 029 ; (С) Авторские права на файлы-приложения принадлежат подписчикам рассылки ; "Ассемблер? Это просто! Учимся программировать" ; Автор рассылки: ; Калашников Олег Александрович (e-mail: Assembler@Kalashnikoff.ru) ; http://www.Kalashnikoff.ru ; --- Ассемблирование (получение *.com файла) --- ;При использовании MASM 6.11 - 6.13: ;ML.EXE 4Bh(1).asm /AT ;При использовании TASM: ;TASM.EXE 4Bh(1).asm ;TLINK.EXE 4Bh(1).obj /t/x ;______________________________________________________ ;__________________________________________________________________________ ; ;!!! ВНИМАНИЕ! Сперва прочтите 29 выпуск, иначе ничего не будет понятно !!! ;__________________________________________________________________________ ;Программа загружает файл (File) НЕ через COMMAND.COM с командной строкой ;(Comm_line) 'abc'. .186 ;shr bx,4 работает на 186+ процессоре! CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h Start: mov bx,offset Finish shr bx,4 inc bx mov ah,4Ah int 21h ;Ужимаем размер отведенной памяти до метки Finish ;Ужимаем стек, т.к. он находится в "хвосте" сегмента, на место которого ;будет загружена программа mov sp,0FFh ; --- Готовим EPB --- mov bx,offset EPB mov C_F,cs ;Сегмент командной строки (смещение уже занесено! См. ниже) ; --- Сохраняем ВСЕ регистры, т.к. они будут разрушены!!! --- pusha push ds push es mov SS_Seg,ss mov SP_Seg,sp ; --- Запускаем программу --- mov ah,4Bh ;Функция EXEC (EXECute - запус программы) mov dx,offset File ;Имя файла для запуска mov al,0 ;Загрузка и запуск int 21h ; --- Восстанавливаем регистры --- mov ss,cs:SS_Seg mov sp,cs:SP_Seg pop es pop ds popa mov ah,9 jnc OK ;Не было ошибок - сообщаем  ;ОШИБКА ПРИ ЗАПУСКЕ! mov dx,offset Mess_Error int 21h int 20h ;Успешная загрузка программы OK: mov dx,offset Mess_OK int 21h int 20h ;Вот, что мы получим, если с помощью данной программы мы загрузим DN, ;а из DN - Volcov Commander (вырезка из VC): ; Размер Программа Перехватываемые прерывания ;---------------------------------------------------- ; 53 776 DOS 7.10 01 02 03 04 0E <==== Системная часть DOS ; 64 system 19 ; 6 928 KEYB 09 E0 ; 3 824 WIN EA F5 ; 3 120 vmm32 33 67 ; 1 280 DN.COM FF <==== Из DN загружаю 4BH(1).COM ; 7 456 COMMAND 2E <==== Первым грузится Command.com ; 864 4BH(1).COM <==== Потом только 4BH(1).COM ; 1 296 dn.com 2F <==== 4BH(1) загружает DN.COM ; 7 264 COMMAND 22 <==== Из DN загружаю VC (опять через Command.com!) ; 76 096 VC.COM 00 1B 21 23 24 <==== VC загружен! ;491 200 free memory ;ОБРАТИТЕ ВНИМАНИЕ, что 4BH(1).COM НЕ загружает COMMAND.COM, в отличие от ;DN.COM! Т.е. мы грузим программу напрямую! ;ЕЩЕ МОМЕНТ: 4BH(1).COM естественно НЕ перехватывает НИКАКИХ прерываний, что ;видно из приведенной выше таблицы. Это называется "пассивный полурезидент". ;Он получит управление только тогда, когда отработают ВСЕ загруженные после ;него программы! Т.е. нам нужно будет выйти из VC (COMMAND.COM автоматически ;выгружается), а затем из DN. ;Суть понятна? Уверен, что так! ;Файл, который будем загружать File db 'test.com',0 ;File db 'c:\dn\dn.com',0 ;Командная строка: ;5 - длина строки (включая 0Dh) ;' abcd' - сама строка (первый символ - пробел!) ;0Dh - признак окончания строки Comm_line db 5,' abcd',0Dh ; === Exec Parameter Block (EPB) для функции 4Bh === EPB: Env dw 0 ;Сегмент среды (окружения DOS) для загружаемой программы C_O dw offset Comm_line ;Смещение командной строки + C_F dw 0 ;+ сегмент командной строки dd 0 ;FCB (не используется) dd 0 ;FCB (не используется) Len dw $-EPB ;Длина EPB Mess_OK db 0Dh,0Ah,0Ah, 'Сообщение от 4B(1).com: Программа была успешно загружена и выполнена!',0Ah,0Dh,0Ah,0Ah,'$' Mess_Error db 0Dh,0Ah,0Ah, 'Сообщение от 4B(1).com: Файл не найден!',0Ah,0Dh,0Ah,0Ah,'$' ; Переменные для хранения сегментных регистров SS_Seg dw ? SP_Seg dw ? ; Метка конца программы (урезаем память до этой метки) Finish equ $ CSEG ends end Start 4BH(2).asm

; 4Bh(2).ASM - программа к рассылке № 029 ;__________________________________________________________________________ ; ;!!! ВНИМАНИЕ! Сперва прочтите 29 выпуск, иначе ничего не будет понятно !!! ;__________________________________________________________________________ ;Программа загружает файл (File) используя COMMAND.COM с командной строкой ;(Comm_param) 'abc'. .186 CSEG segment assume cs:CSEG, ds:CSEG, es:CSEG, ss:CSEG org 100h Start: mov bx,offset Finish shr bx,4 inc bx mov ah,4Ah int 21h ;Ужимаем размер отведенной памяти до метки Finish ;Ужимаем стек, т.к. он находится в "хвосте" сегмента, на место которого ;будет загружена программа mov sp,0FFh ; --- Готовим EPB --- mov bx,offset EPB mov C_F,cs ;Сегмент командной строки (смещение уже занесено! См. ниже) ; --- Сохраняем ВСЕ регистры, т.к. они будут разрушены!!! --- pusha push ds push es mov SS_Seg,ss mov SP_Seg,sp ; --- Запускаем программу --- mov ah,4Bh ;Функция EXEC (EXECute - запус программы) mov dx,offset File ;Имя файла для запуска mov al,0 ;Загрузка и запуск int 21h ; --- Восстанавливаем регистры --- mov ss,cs:SS_Seg mov sp,cs:SP_Seg pop es pop ds popa mov ah,9 jnc OK ;Не было ошибок - сообщаем  ;ОШИБКА ПРИ ЗАПУСКЕ! mov dx,offset Mess_Error int 21h int 20h ;Успешная загрузка программы OK: mov dx,offset Mess_OK int 21h int 20h ;Вот, что мы получим, если с помощью данной программы мы загрузим DN, ;а из DN - Volcov Commander (вырезка из VC): ; Размер Программа Перехватываемые прерывания ;---------------------------------------------------- ;53 776 DOS 7.10 01 02 03 04 0E ; 64 system 19 ; 6 928 KEYB 09 E0 ; 3 824 WIN EA F5 ; 3 120 vmm32 33 67 ; 1 280 DN.COM FF <==== Из DN загружаю 4BH(2).COM ; 7 456 COMMAND 2E <==== Первым грузится Command.com ; 880 4BH(2).COM <==== Потом только 4BH(2).COM ; 7 264 command <==== 4BH(2) загружает COMMAND.COM! ; 1 296 DN.COM 2F <==== И только потом DN.COM ; 7 280 COMMAND 22 <==== И т.д. (как из прошлого примера) ;76 096 VC.COM 00 1B 21 23 24 ;Файл, который будем загружать File db 'c:\command.com',0 ;Командная строка здесь должна содержать (см. ниже): ;1. Длина командной строки (до 256 байт) (Comm_size) ;2. "/С ", указывающий COMMAND.COM, что нужно загрузить, выполнить и выйти ; из COMMAND.COM (Comm_switch) ;3. Имя файла для загрузки (Comm_file) ;4. Командная строка для загружаемого из COMMAND.COM файла (Comm_param) Comm_line: Comm_size db 21 Comm_switch db ' /C ' Comm_file db 'c:\dn\dn.com' ;Comm_file db 'test(1).com' ;Comm_file db 'dir /p' Comm_param db ' abc' Comm_last db 0Dh ;ВНИМАНИЕ! Через COMMAND.COM можно выполнять также ЛЮБЫЕ внутренние ;команды DOS, как DIR, CLS, TYPE и пр (см. выше "dir /p"). ;!!! НЕ ЗАБЫВАЙТЕ ИЗМЕНЯТЬ ДЛИНУ КОММАНДНОЙ СТРОКИ !!! ; === Exec Parameter Block (EPB) для функции 4Bh === EPB: Env dw 0 ;Сегмент среды (окружения DOS) для загружаемой программы C_O dw offset Comm_line ;Смещение командной строки + C_F dw 0 ;+ сегмент командной строки dd 0 ;FCB (не используется) dd 0 ;FCB (не используется) Len dw $-EPB ;Длина EPB Mess_OK db 0Dh,0Ah,0Ah, 'Сообщение от 4B(2).com: Программа была успешно загружена и выполнена!',0Ah,0Dh,0Ah,0Ah,'$' Mess_Error db 0Dh,0Ah,0Ah, 'Сообщение от 4B(2).com: Файл не найден!',0Ah,0Dh,0Ah,0Ah,'$' ; Переменные для хранения сегментных регистров SS_Seg dw ? SP_Seg dw ? ; Метка конца программы (урезаем память до этой метки) Finish equ $ CSEG ends end Start

Test.asm

; TEST.ASM - дополнительная программа к рассылке № 29 ; (С) Авторское право на файл-приложение принадлежит подписчикам рассылки "Ассемблер? Это просто! Учимся программировать" ; Автор рассылки: Калашников Олег Александрович (e-mail: Assembler@Kalashnikoff.ru) ; http://www.Kalashnikoff.ru ; === Начало программы: === cseg segment assume cs:cseg, ds:cseg, ss:cseg, es:cseg org 100h Begin: mov ah,9 mov dx,offset Mess_start int 21h mov ah,2 ;Функция вывода одного символа на экран mov si,80h ;Адрес командной строки lodsb or al,al lodsb jnz Next_char mov ah,9 mov dx,offset Error_String int 21h ret Next_char: lodsb ;Получаем первый символ cmp al,0Dh ;Это 0Dh? jz End_param ;Да - тогда первый параметр закончился  Next_param: mov dl,al ;Нет, не нуль. Тогда выводим полученный символ... int 21h ;...на экран в текущую позицию курсора jmp short Next_char ; Приступаем к следующему символу...  End_param: int 20h Mess_start db 'Сообщение от Test.com: Командная строка: $' Error_String db 'НЕ ВВЕДЕНА!',0Ah,0Dh,0Ah,0Ah,'$' cseg ends end Begin

Сегодня целый выпуск посвящен функции 4Bh прерывания 21h (загрузка и запуск программ). Почему так? Дело в том, что запустить программу на Ассемблере - задача нетривиальная, как может показаться с первого взгляда, тем более, что поступает много вопросов по этой теме.

Итак-с, начнем...

Обратите внимание, что в приложении находятся три небольших файла: 4BH(1).ASM, 4BH(2).ASM и Test.asm. Не спешите их ассемблировать! Прочтите сперва выпуск до конца!

Прежде, чем запустить программу, необходимо тщательно подготовиться. Что нужно сделать:

1. Выделить память для загружаемой программы;

2. Ужать стек, если это com-файл;

3. Сохранить необходимые регистры;

4. Подготовить EPB;

5. Подготовить строку с именем файла, который будем запускать;

6. Подготовить командную строку;

7. Сохранить сегментные регистры (если необходимо);

8. Сохранить стековые регистры (SS и SP) в переменных;

9. Запустить программу (вызвать int 21h).

С этого момента (с момента вызова 21h-ого прерывания) наша программа (родительская) находится в памяти до тех пор, пока запущенная (порожденная) программа не отработает.

Как только она отработала, управление получает наша (родительская) программа. Что делаем дальше:

1. Восстанавливаем стековые регистры (SS и SP);

2. Восстанавливаем сохраненные в стеке регистры (сегментные и пр., если их сохраняли);

3. Производим другие необходимые действия.

Вот, собственно, и все.

___________________

Теперь рассмотрим, как это все происходит на практике.

Шаг 1: Отводим (урезаем) память

(1) mov bx,offset Finish

(2) shr bx,4

(3) inc bx

(4) mov ah,4Ah

(5) int 21h Надеюсь, что вы помните о том, что традиционно метка Finish у нас последняя.

Зачем нужно урезать память перед загрузкой?

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

В первой строке загружаем в регистр BX адрес (смещение) последнего байта нашей программы. Это понятно.

Зачем же во второй строке мы сдвигаем на 4 бита вправо это смещение? Дело в том, что функция 4Ah (изменение размера отведенной памяти) требует указания в регистре BX блока памяти размером 16 байт. Т.е., загрузив в BX единицу, мы отведем не один байт, а сразу шестнадцать (т.е. один параграф).

Загружая в BX адрес последнего байта нашей программы, мы получаем не количество параграфов, а количество байт. Т.о., не разделив BX на 16, мы отведем памяти в 16 раз больше. Делим же мы так: просто сдвинем число в BX на 4 вправо, что эквивалентно делению BX на 16. Мы это уже проходили...

А для чего увеличиваем BX на единицу (3)? Для уверенности. Лучше отведем на 16 байт больше, чем на один меньше...

Теперь у нас BX содержит количество параграфов (блоков памяти по 16 байт), которые заняла наша программа в памяти.

___________

Шаг 2: Переносим стек в область PSP (0FEh).

(1) mov sp,0FEh Зачем? Вспомните, что при загрузке com-программы в память, смещение стека находится в самом низу сегмента, в который загрузилась программа (т.е. 0FFFEh). Но мы ведь ужимаем память до метки Finish! Получается, что программа будет загружаться в первый байт после этой метки. Т.о. мы затираем стек.

Чтобы этого не произошло, перенесем стек в область PSP (все равно она не используется в нашем примере, а это лишние 256 байт, куда можно переместить указатель стека).

___________

Шаг 3: Готовим EPB.

(1) mov bx,offset EPB

(2) mov C_F,cs Что такое EPB?

EPB - EXEC Parameter Block - блок параметров функции загрузки файла. В этом блоке должна содержаться следующая информация:

Смещение Длина Содержимое 00h 2 Сегмент окружения DOS для порождаемого процесса 02h 4 Смещение и сегмент адреса командной строки 06h 4 Первый адрес блока FCB 0Ah 4 Второй адрес блока FCB 0Eh 2 Длина EPB А вот, как мы обозначаем его в Ассемблере:

; === Exec Parameter Block (EPB) для функции 4Bh ===

EPB:

Env dw 0 ;Сегмент среды (окружения DOS) для загружаемой программы

C_O dw offset Comm_line ;Смещение командной строки +

C_F dw 0 ;+ сегмент командной строки

dd 0 ;FCB 1

dd 0 ;FCB 2

Len dw $-EPB ;Длина EPB Сравните с приведенной выше таблицей.

Сегмент окружения DOS.

Мы уже знаем, что такое окружение DOS. Рассматривали подробно данную тему в предыдущих выпусках. Но на всякий случай напомню.

Окружение DOS хранит в себе настройки (текущие параметры), которые передаются, в частности, при загрузке ОС в файле autoexec.bat. Например:

TEMP=C:\WINDOWS\TEMP

PROMPT=$p$g

COMSPEC=C:\WINDOWS\COMMAND.COM

PATH=D:\PERL\BIN;C:\WINDOWS

windir=C:\WINDOWS

BLASTER=A220 I5 D1 H5 P330 T6 E620

Посмотреть текущие параметры можно выполнив внутреннюю команду set в приглашении DOS.

Итак, если в поле "Сегмент окружения DOS..." находится 0, то порожденная программа получит те параметры, которые получила наша программа (т.е. значения передаются по умолчанию).

Если же для порождаемого процесса (для загружаемой программы) мы хотим передать свои параметры, то нам нужно выделить блок памяти в отдельном сегменте, внести туда необходимые значения и в EPB по смещению 0 занести сегмент отведенного блока (как это делать - рассмотрим ниже).

Но, как правило, в это поле практически все программы заносят нуль.

Для чего нужно вообще создавать свое окружение DOS? Ну, в разных случаях... Например, некоторая антивирусная программа, запуская чужую, может не передать текущее окружение, принимая во внимание тот факт, что некоторые вирусы размножаются по пути (PATH), который они сами находят в памяти (вспомним из прошлых выпусков, что найти сегмент окружения DOS можно по смещению 2Ch сегмента, в который загрузилась программа. Смещение всегда будет равно нулю).

Вроде все понятно. Но имейте в виду, что если вы решили создать свое окружение, то нужно придерживаться определенных правил. Как именно устроено окружение DOS - смотрите 23 выпуск рассылки. Там все подробнейшим образом расписано. Вот по такому образу и подобию вам необходимо будет создавать свое окружение для порождаемого процесса.

Обратите также внимание, что нам нужно заносить только один байт (смещение), а не два (сегмент + смещение). Как уже отмечалось выше, смещение всегда будет равно нулю.

Смещение и сегмент командной строки.

Здесь все просто. Создаем некий массив и заносим в это поле ВНАЧАЛЕ смещение, а ЗАТЕМ сегмент этого массива.

Например, так (командная строка):

Comm_line db 5,' abcd',0Dh А теперь обратите внимание, что мы по умолчанию в EPB заносим смещение, а затем "вручную" сегмент данной командной строки (см. выше EPB):

C_O dw offset Comm_line ;Смещение командной строки

mov C_F,cs ;Сегмент командной строки

Уверен, что вы знаете, как устроена командная строка, т.к. мы неоднократно ее уже разбирали. Тем не менее, опишу вкратце (по приведенному выше примеру (Comm_line)):

Первый байт - длина строки (включая символ 0Dh);

Остальные байты - сама строка;

Последний байт - 0Dh (обязательно!).

Первый и второй адрес блоков FCB.

Как правило, уже не используются, поэтому я не буду их вообще касаться в данной рассылке. Скажу только, что заносите в них всегда нули, и все будет хорошо!

________________

Шаг 4: Сохраняем регистры

(1) pusha

(2) push ds

(3) push es

(4) mov SS_Seg,ss

(5) mov SP_Seg,sp Заносить в стек или сохранять иным образом такие регистры, как AX, BX, CX, DX, SI, DI и т.п. не обязательно, если вы, конечно, не сохраняете в них информацию, которая понадобится после завершения порожденного процесса. Однако, в нашем примере мы это делаем. Для наглядности и полноты (строка (1)).

Сегментные регистры (DS и ES) также сохранять не обязательно, если они все перед запуском новой программы были равны CS. Просто в таком случае (если они равны CS), мы можем после завершения порожденного процесса выполнить следующие действия:

push cs

push cs

pop ds

pop es

Но мы сегментные регистры все-таки сохраним (строки (2) - (3)).

Затем идут регистры указателя стека (SS:SP). Сохранить в стеке мы их не можем. Думаю, что это понятно и так. Для такой цели выделяем две переменные, в которые их и занесем (SS_Seg, SP_Seg). Иного способа не существует...

Шаг 5: Запуск программы

(1) mov ah,4Bh

(2) mov dx,offset File

(3) mov al,0

(4) int 21h Итак, функция 4Bh (1). В DX заносим смещение строки с файлом (2). Это все просто.

Далее. Подфункция 0 функции 4Bh прерывания 21h - загрузка и запуск программы (3).

Это значит, что программа будет загружена в память и запущена.

Существуют также подфункция 1, которая только загружает программу, но не передает ей управление.

И подфункция 3 - загрузка оверлея.

Подфункции 1 и 3 используются редко, и мы их пока рассматривать не будем. Наша цель - заставить программу загрузиться и выполниться.

Все! После выполнения строки (4) пойдет загрузка. Следующая за ней строка получит управление только тогда, когда завершит работу загруженная программа.

_________________

После того, как запущенная программа отработала, необходимо произвести "восстановительные работы", а именно:

Шаг 1: Восстановление регистров стека

mov ss,cs:SS_Seg

mov sp,cs:SP_Seg Это первое, что мы должны сделать, т.к. запущенный процесс поменял эти регистры, а без стека мы как без рук!

Обратите внимание: т.к. мы не уверены, что отработанная программа не поменяла регистры DS, то обращаемся к переменным SS_Seg и SP_Seg, используя регистр CS, который, как мы уже знаем, всегда равен тому сегменту, в котором выполняется текущая команда.

Шаг 2: Восстановление иных сохраненных регистров

pop es

pop ds

popa В данном случае мы сохраняли эти регистры (см. выше).

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

Ну что, уважаемые читатели, сложно? Нисколько! Почему же тогда поступало столько вопросов на эту тему?

Удачных вам экспериментов! Дополнительную информацию вы, как всегда, найдете в файлах-приложениях. Уверен, что вы разберетесь! Внимательно ознакомьтесь с тремя прилагаемыми файлами. Это позволит вам лучше понять принцип запуска программ на Ассемблере!

Наши партнеры 1. Рассылка "Уроки для начинающих программистов".

Одна из лучших рассылок по программированию для начинающих. Проект Эдуарда Дмитриева.

___________

2. Рассылка Сергея Никифорова "Программирование на Visual Basic и ASP" на Subscribe.ru (код рассылки: comp.soft.prog.vbs).

Название и сайт автора: Visual Basic Streets, http://www.vbstreets.ru.

___________

3. Рассылка "Мир программирования на Visual BASIC и HTML" (http://soobcha-vb.narod.ru/alex):

Подписаться на рассылку Кувалина Алексея

Мир программирования на Visual BASIC и HTML С уважением,

Калашников Олег: Assembler@Kalashnikoff.ru

Мой ICQ No.: 68951340

URL сайта подписчиков: http://www.Kalashnikoff.ru

Форма для подачи вопроса: http://www.Kalashnikoff.ru/Experts/Question.html

______________

По вопросам сотрудничества, рекламы и спонсорства обращайтесь:

Публичное размещение материала из рассылки: Cooperation@Kalashnikoff.ru

Реклама на сайте, в книге и рассылках: http://www.Kalashnikoff.ru/Reklama.html, Reklama@Kalashnikoff.ru

Издание книги по материалам рассылки (спонсорство): Sponsor@Kalashnikoff.ru

(C) Москва, 2001. Авторское право принадлежит Калашникову О.А. Публичное размещение материала из рассылки, а также его использование полностью или частично в коммерческих или иных подобных целях без письменного согласия автора влечет ответственность за нарушение авторских прав. u="u496.71.spylog.com";d=document;nv=navigator;na=nv.appName;p=1; bv=Math.round(parseFloat(nv.appVersion)*100); n=(na.substring(0,2)=="Mi")?0:1;rn=Math.random();z="p="+p+"&rn="+rn;y=""; y+=""; y+=""; y+=""; d.write(y);if(!n) { d.write("

Соседние файлы в папке Выпуски