- •Тема 1.
- •Понятия вычислительного процесса и Ресурса
- •Процессы и треды
- •Независимые и взаимодействующие вычислительные процессы
- •Прерывания.
- •Файловая система ntfs (New Technology File System)
- •Интерфейс прикладного программирования
- •Реализация функций api на уровне ос
- •Реализация функций api на уровне системы программирования
- •Реализация функций api с помощью внешних библиотек
- •Платформенно-независимый интерфейс posix
- •Семафорные примитивы Дейкстры
- •Мьютексы
- •Мониторы Хоара
- •Почтовые ящики
- •Конвейеры
- •Организация очереди на массиве
- •Очереди сообщений
- •Понятие тупиковой ситуации при выполнении параллельных вычислительных процессов
- •Студенты, не защитившие лабораторные работы, к сдаче зачетной единицы не допускаются
- •Общие сведения
- •Удаление элемента из списка.
- •Теоретическая часть (в популярном для студентов стиле).
- •0030:4012 (Всё шестнадцатиричное)
- •Выделение памяти.
- •(Каждый блок представляет байт)
- •Чтобы узнать, что происходит в памяти, при размещении и извлечении значений в стеке, см. На рисунок ниже:
- •Регистр eax почти всегда используется для хранения результата процедуры.
- •Строки.
- •Заполнение данными.
- •Все команды перехода имеют один операнд: смещение для перехода.
- •Организация циклов.
- •Имеются также другие формы:
- •Xor (не или) устанавливает бит результата в 1, если бит источника отличается от бита приемника. Not инвертирует бит источника.
- •Подпрограммы.
- •Структуры.
- •Упрощённый вызов api функций в tasm.
- •А вот и операторы, которые вы можете использовать:
- •Пример: команды ror (циклический сдвиг вправо)
- •Стековые операции.
Регистр eax почти всегда используется для хранения результата процедуры.
Это также применимо к функциям windows. Конечно, вы можете использовать любой другой регистр в ваших собственных процедурах, но это стандарт.
Процессоры могут быть 386, 486, 586, обычно всегда стоит 386p, но ничто вам не мешает поставить 486p или 586. Модель памяти всегда flat и никакой другой не может быть. Вызов подпрограмм обычно всегда stdcall, стандарт вызова почти всех API функций. Секция .data секция с инициализированными данными она включается в исполняемый файл. Секция .data? секция с неинициализированными данными, она не включается в исполняемый файл и появляется только тогда, когда программа загружается в память. Секция .const секция констант. Секция .code содержит исполняемый код программы. В конце программы всегда должно стоять слово end, которая задаёт точку входа программы, т.е. место с которого начнётся выполняться программа. Секции .data, .data? имеют полный доступ. Разумеется, секции .const и .code имеют атрибут доступа - только чтение. Секция .const наиболее редко встречается в программах, так как константы можно задавать с помощью макроопределений.
При программировании под Win32 мы не имеем доступ к портам ввода вывода и не можем вызывать прерывания (самые главные команды в DOS), у нас есть только WIN API, которые экспортируют системные библиотеки. Вызывая API функцию, вы просто передаёте управление точке входа функции (точка входа функции это первая инструкция функции), сама функция находится где-то в памяти вашего процесса внутри некоторой библиотеки. API функции находятся в библиотеках kernel32.dll, user32.dll, gdi32.dll (классика) advapi32.dll и т.д., для того чтобы использовать некоторую функцию этих библиотек надо сначала загрузить нужную библиотеку в свою память, либо включить используемые функции в таблицу импорта и тогда загрузчик загрузит библиотеки за вас. О kernel32.dll можно не волноваться, потому что эта библиотека есть в каждом процессе в любом случае, тем более она там существует ещё до запуска главной нити процесса, она даже проецируется в вашу память всегда по одинаковым адресам. Как я уже говорил все функции, используют модель вызова stdcall, а значит, параметры подпрограмме передаются "задом-наперёд" и вызываемый очищает стек. Общий вид вызова API функции будет такой:
Push параметр 3 Push параметр 2 Push параметр 1
Call функция ; если быть точнее то здесь должен стоятб ажрес функции ; т.е. адрес её точки входа
Каждая программа в Win32 в конце своего выполнения ОБЯЗАТЕЛЬНО должна вызвать функцию ExitProcess. Сами подумайте, после выполнения последней инструкции программы, дальше идёт пустота, даже если там что-то осмысленное, все равно у выделенной памяти есть конец, а после конца идёт невыделенная (т.е. несуществующая) память. Процессор начнёт выполнять непоймёшь чё, пойдут глюки, и ваша программа даст в конце хорошо всем знакомый звук - "ДУНГ". А это уже бессмыслица. Вот определение ExitProcess из MS SDK:
Секции .data, .data? и .const нужны для определения данных программы. Место под данные резервируется с помощью директив db, dw, dd, dq, dt.
db - 1 байт
dw - 2 байта - 1 слово dd - 4 байта - 2 слова dq - 8 байт - 4 слова dt - 10 байт
Секция .data наиболее универсальная мы резервируем память под данные и сразу же инициализируем их, т.е. задаём им начальные значения. Все данные из этой секции включаются в исполнимый файл. Секция .data? менее гибкая, так как данные нельзя инициализировать. Все данные в этой секции не включаются в исполнимый файл, поэтому место только резервируется, но начальные значения не задаются. Данные в обеих секциях имеют полный режим доступа. Секция .const предназначена только чтения. Но ошибок не возникает при попытке изменить эти данные (????). Эта секция самая бесполезная.
.data
Perem dd 0000FF11h X1 dw 01235h Binary db 00111010b
dd 11225599h decimal dw 28d
large dq 01123456789ABCDEFh dw 1011100101010111b .data? Perem1 dd ? Perem2 dq ? Perem5 dw ? Dd ? Dw ? Perem4 db ?
..const Const1 dd 012345678h dw 768d