#16_TOS
АДРЕСНОЕ ПРОСТРАНСТВО — набор адресов, который может быть использован процессом для обращения к памяти.
АДРЕСНОЕ ПРОСТРАНСТВО — набор адресов, который может быть использован процессом для обращения к памяти.
#17_TOS
СВОПИНГ — размещение в памяти всего процесса целиком, запуск этого процесса на некоторое время, а затем сброс на диск (ПЗУ).
СВОПИНГ — размещение в памяти всего процесса целиком, запуск этого процесса на некоторое время, а затем сброс на диск (ПЗУ).
#18_SYSCL_TOS
Отличительной чертой модели ввода-вывода в UNIX системах является понятие УНИВЕРСАЛЬНОСТИ ВВОДА-ВЫВОДА.
Это означает, что одни и те же системные вызовы (open(), read(), write(), close() и т.д.) используются для выполнения ввода-вывода во всех типах файлов, включая устройства (учитывая, что в UNIX системах все - в том числе и устройства представляются в виде файла).
По сути, ядро выдает один тип файла — последовательный поток байтов, к которому, в случае файлов на дисках, дисков и ленточных накопителей, можно получить произвольный доступ с помощью системного вызова
.
Отличительной чертой модели ввода-вывода в UNIX системах является понятие УНИВЕРСАЛЬНОСТИ ВВОДА-ВЫВОДА.
Это означает, что одни и те же системные вызовы (open(), read(), write(), close() и т.д.) используются для выполнения ввода-вывода во всех типах файлов, включая устройства (учитывая, что в UNIX системах все - в том числе и устройства представляются в виде файла).
По сути, ядро выдает один тип файла — последовательный поток байтов, к которому, в случае файлов на дисках, дисков и ленточных накопителей, можно получить произвольный доступ с помощью системного вызова
lseek()
.
#19_TP_BASH
ФИЛЬТР — часто обозначает программу, считывающую вводимые в нее данные из stdin, выполняет преобразования этого ввода и записывает преобразованные данные в stdout.
Примеры программ-фильтров:
cat,
grep,
tr,
sort,
wc,
sed,
awk.
ФИЛЬТР — часто обозначает программу, считывающую вводимые в нее данные из stdin, выполняет преобразования этого ввода и записывает преобразованные данные в stdout.
Примеры программ-фильтров:
cat,
grep,
tr,
sort,
wc,
sed,
awk.
#20_TOS
ПРОЦЕСС в LINUX — экземпляр выполняемой программы.
Когда программа выполняется, ядро загружает ее код в виртуальную память, выделяет память под переменные программы и определяет учетные структуры данных ядра для записи различной информации о процессе (имеются в виду идентификатор процесса, код завершения, пользовательские и групповые идентификаторы).
С точки зрения ядра процессы — объекты, между которыми ядро должно делить различные ресурсы компьютера.
В случае с ограниченными ресурсами, например памятью, ядро изначально выделяет некоторый их объем процессу и регулирует это выделение в ходе жизненного цикла процесса, реагируя на потребности процесса и общие потребности системы в этом ресурсе.
Когда процесс завершается, все такие ресурсы высвобождаются для повторного использования другими процессами.
Другие ресурсы, такие как время центрального процессора и сетевой трафик, являются возобновляемыми, но должны быть поровну поделены между всеми процессами.
ПРОЦЕСС в LINUX — экземпляр выполняемой программы.
Когда программа выполняется, ядро загружает ее код в виртуальную память, выделяет память под переменные программы и определяет учетные структуры данных ядра для записи различной информации о процессе (имеются в виду идентификатор процесса, код завершения, пользовательские и групповые идентификаторы).
С точки зрения ядра процессы — объекты, между которыми ядро должно делить различные ресурсы компьютера.
В случае с ограниченными ресурсами, например памятью, ядро изначально выделяет некоторый их объем процессу и регулирует это выделение в ходе жизненного цикла процесса, реагируя на потребности процесса и общие потребности системы в этом ресурсе.
Когда процесс завершается, все такие ресурсы высвобождаются для повторного использования другими процессами.
Другие ресурсы, такие как время центрального процессора и сетевой трафик, являются возобновляемыми, но должны быть поровну поделены между всеми процессами.
#21_TP_TOS
МОДЕЛЬ ПАМЯТИ ПРОЦЕССА в LINUX.
Процесс логически делится на следующие части, известные как сегменты:
- ТЕКСТ — инструкции программы;
- ДАННЫЕ — статические переменные, используемые программой;
- ДИНАМИЧЕСКАЯ ПАМЯТЬ (куча) — область, из которой программа может динамически выделять дополнительную память;
- СТЕК — часть памяти, которая может расширяться и сжиматься по мере вызова
функций и возвращения из них и которая используется для выделения хранилища
под локальные переменные и информацию о взаимосвязанности вызовов функций.
МОДЕЛЬ ПАМЯТИ ПРОЦЕССА в LINUX.
Процесс логически делится на следующие части, известные как сегменты:
- ТЕКСТ — инструкции программы;
- ДАННЫЕ — статические переменные, используемые программой;
- ДИНАМИЧЕСКАЯ ПАМЯТЬ (куча) — область, из которой программа может динамически выделять дополнительную память;
- СТЕК — часть памяти, которая может расширяться и сжиматься по мере вызова
функций и возвращения из них и которая используется для выделения хранилища
под локальные переменные и информацию о взаимосвязанности вызовов функций.
#22_TOS_SYSCL
СОЗДАНИЕ ПРОЦЕССА И ВЫПОЛНЕНИЕ ПРОГРАММЫ в LINUX.
Процесс может создать новый процесс с помощью системного вызова:
Процесс, вызывающий fork(), известен как родительский процесс, а новый процесс называется дочерним процессом.
Ядро создает дочерний процесс путем изготовления дубликата родительского процесса.
Дочерний процесс наследует копии родительских сегментов данных, стека и кучи, которые затем могут изменяться независимо от своих родительских копий. (Текст программы размещается в области памяти с пометкой «только для чтения» и совместно используется двумя процессами.)
Дочерний процесс запускается либо для выполнения другого набора функций в том
же самом коде, что и у родительского процесса, либо зачастую для использования системного вызова
с целью загрузки и выполнения совершенно новой программы.
Вызов execve( ) удаляет существующие сегменты текста, данных, стека и кучи, заменяя их новыми сегментами, основываясь на коде новой программы.
У вызова execve( ) есть ряд надстроек в виде родственных функций библиотеки языка C с несколько отличающимся интерфейсом, но сходной функциональностью.
СОЗДАНИЕ ПРОЦЕССА И ВЫПОЛНЕНИЕ ПРОГРАММЫ в LINUX.
Процесс может создать новый процесс с помощью системного вызова:
fork()
Процесс, вызывающий fork(), известен как родительский процесс, а новый процесс называется дочерним процессом.
Ядро создает дочерний процесс путем изготовления дубликата родительского процесса.
Дочерний процесс наследует копии родительских сегментов данных, стека и кучи, которые затем могут изменяться независимо от своих родительских копий. (Текст программы размещается в области памяти с пометкой «только для чтения» и совместно используется двумя процессами.)
Дочерний процесс запускается либо для выполнения другого набора функций в том
же самом коде, что и у родительского процесса, либо зачастую для использования системного вызова
execve();
с целью загрузки и выполнения совершенно новой программы.
Вызов execve( ) удаляет существующие сегменты текста, данных, стека и кучи, заменяя их новыми сегментами, основываясь на коде новой программы.
У вызова execve( ) есть ряд надстроек в виде родственных функций библиотеки языка C с несколько отличающимся интерфейсом, но сходной функциональностью.
#23_TOS
PID — уникальный целочисленный идентификатор процесса.
PPID — у каждого процесса также есть атрибут идентификатора родительского процесса, идентифицирующий процесс, запросивший у ядра создание данного процесса.
PID — уникальный целочисленный идентификатор процесса.
PPID — у каждого процесса также есть атрибут идентификатора родительского процесса, идентифицирующий процесс, запросивший у ядра создание данного процесса.
#24_TOS
ЗАВЕРШЕНИЕ ПРОЦЕССА и КОД ЗАВЕРШЕНИЯ в LINUX.
Процесс может быть завершен двумя способами:
— запросом своего собственного завершения с использованием системного вызова
(или родственной ему библиотечной функции exit( ));
— путем его уничтожения извне с помощью сигнала.
В любом случае процесс выдает код завершения, небольшое неотрицательное целое число, которое может быть проверено родительским процессом с использованием системного вызова
В случае вызова _exit( ) процесс явным образом указывает свой собственный код завершения.
Если процесс уничтожается сигналом, код завершения устанавливается по типу сигнала, уничтожившего процесс.
По соглашению, код завершения 0 служит признаком успешного завершения процесса, а ненулевое значение служит признаком возникновения какой-то ошибки.
Большинство оболочек позволяют получить код завершения последней выполненной программы с помощью переменной оболочки по имени $?.
ЗАВЕРШЕНИЕ ПРОЦЕССА и КОД ЗАВЕРШЕНИЯ в LINUX.
Процесс может быть завершен двумя способами:
— запросом своего собственного завершения с использованием системного вызова
_exit();
(или родственной ему библиотечной функции exit( ));
— путем его уничтожения извне с помощью сигнала.
В любом случае процесс выдает код завершения, небольшое неотрицательное целое число, которое может быть проверено родительским процессом с использованием системного вызова
wait();
В случае вызова _exit( ) процесс явным образом указывает свой собственный код завершения.
Если процесс уничтожается сигналом, код завершения устанавливается по типу сигнала, уничтожившего процесс.
По соглашению, код завершения 0 служит признаком успешного завершения процесса, а ненулевое значение служит признаком возникновения какой-то ошибки.
Большинство оболочек позволяют получить код завершения последней выполненной программы с помощью переменной оболочки по имени $?.
#25_TOS
ПРОЦЕСС INIT в LINUX.
При загрузке системы ядро создает особый процесс, который называется
init — «родитель всех процессов».
Он ведет свое происхождение от программного файла
Все процессы в системе создаются (используя fork()) либо процессом init, либо одним из его потомков.
Процесс init всегда имеет идентификатор процесса 1 и запускается с правами доступа суперпользователя.
Процесс init не может быть уничтожен (даже привилегированным пользователем) и завершается только при завершении работы системы.
Основной задачей init является создание и слежение за процессами, требующимися работающей системе.
ПРОЦЕСС INIT в LINUX.
При загрузке системы ядро создает особый процесс, который называется
init — «родитель всех процессов».
Он ведет свое происхождение от программного файла
/sbin/init.
Все процессы в системе создаются (используя fork()) либо процессом init, либо одним из его потомков.
Процесс init всегда имеет идентификатор процесса 1 и запускается с правами доступа суперпользователя.
Процесс init не может быть уничтожен (даже привилегированным пользователем) и завершается только при завершении работы системы.
Основной задачей init является создание и слежение за процессами, требующимися работающей системе.
#26_TOS
ПРОЦЕССЫ-ДЕМОНЫ в LINUX.
Демон — процесс специального назначения, создаваемый и управляемый системой точно так же, как и другие процессы, но отличающийся от них следующими характеристиками:
— процесс-демон долгоживущий, зачастую запускается при загрузке системы и продолжает свое существование до тех пор, пока работа системы не будет завершена;
— запускается в фоновом режиме, и у него нет управляющего терминала, с которого он мог бы считывать ввод или на который он мог бы записывать вывод.
К примерам процессов-демонов относятся syslogd, который записывает сообщения
в системный журнал, и httpd, который обслуживает веб-страницы посредством протокола передачи гипертекста — Hypertext Transfer Protocol (HTTP).
ПРОЦЕССЫ-ДЕМОНЫ в LINUX.
Демон — процесс специального назначения, создаваемый и управляемый системой точно так же, как и другие процессы, но отличающийся от них следующими характеристиками:
— процесс-демон долгоживущий, зачастую запускается при загрузке системы и продолжает свое существование до тех пор, пока работа системы не будет завершена;
— запускается в фоновом режиме, и у него нет управляющего терминала, с которого он мог бы считывать ввод или на который он мог бы записывать вывод.
К примерам процессов-демонов относятся syslogd, который записывает сообщения
в системный журнал, и httpd, который обслуживает веб-страницы посредством протокола передачи гипертекста — Hypertext Transfer Protocol (HTTP).
#27_Cpp
ПЕРЕГРУЗКА ОПЕРАТОРОВ в С++.
Важно помнить:
перегружаются через методы класса — это требования языка С++.
Унарные операторы:
так же лучше перегружать через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые изменяют левый операнд:
лучше выполнять через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые не изменяют левый операнд:
лучше выполнять через обычные или дружественные функции.
Операторы ввода (>>) и вывода (<<)
нельзя перегружать через методы класса потому что они должны возвращать объекты класса std::istream и std::ostream соответственно.
Их перегрузку лучше реализовывать через обычные или дружественные функции.
ПЕРЕГРУЗКА ОПЕРАТОРОВ в С++.
Важно помнить:
operator=( ) — оператор присваивания;
operator[ ]( ) — индекса;
operator()( ) — вызова функции;
operator->( ) — выбора члена;
перегружаются через методы класса — это требования языка С++.
Унарные операторы:
operator+( ); — унарный плюс;
operator-( ); — унарный минус;
bool operator!( ); — оператор логического НЕ.
так же лучше перегружать через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые изменяют левый операнд:
operator+=( );
operator-=( );
operator*=( );
operator/=( );
operator%=( );
лучше выполнять через методы класса.
Перегрузку бинарных операторов (операторов с двумя операндами), которые не изменяют левый операнд:
operator+( );
operator-( );
operator*( );
operator/( );
operator%( );
лучше выполнять через обычные или дружественные функции.
Операторы ввода (>>) и вывода (<<)
std::istream& operator» (std::istream &in, T& t);
std::ostream& operator« (std::ostream &out, const T& t);
нельзя перегружать через методы класса потому что они должны возвращать объекты класса std::istream и std::ostream соответственно.
Их перегрузку лучше реализовывать через обычные или дружественные функции.
#28_CMPL_DBG_TOS_TP
ELF64 — Executable and Linkable Format 64-bit (выполняемый и связываемый формат для 64 битной системы).
ELF64 — Executable and Linkable Format 64-bit (выполняемый и связываемый формат для 64 битной системы).
#29_CMPL_DBG_TP
DWARF (Debug With Arbitrary Record Format) — отладка с использованием произвольного формата записей.
DWARF (Debug With Arbitrary Record Format) — отладка с использованием произвольного формата записей.
#31_ASM_CMPL_GCC_TP
Последние версии компилятора и линкера GCC по умолчанию генерируют выполняемый код, не зависящий от положения в памяти, или перемещаемый код (position independent executable – PIE).
Это делается для защиты от хакеров, исследующих, как память используется программой, что в итоге позволяет им воздействовать на выполнение программы.
Такая программа слишком сложна для анализа (усложнение делается преднамеренно из соображений обеспечения безопасности).
Ключ компилятора -no-pie — отключает эту защиту и позволяет получить не перемещаемый код.
Последние версии компилятора и линкера GCC по умолчанию генерируют выполняемый код, не зависящий от положения в памяти, или перемещаемый код (position independent executable – PIE).
Это делается для защиты от хакеров, исследующих, как память используется программой, что в итоге позволяет им воздействовать на выполнение программы.
Такая программа слишком сложна для анализа (усложнение делается преднамеренно из соображений обеспечения безопасности).
Ключ компилятора -no-pie — отключает эту защиту и позволяет получить не перемещаемый код.
#32_BASH
Команда ld (GNU линкер в Linux) — используется для компоновки объектных файлов в исполняемые файлы или библиотеки.
Она является частью набора инструментов GNU Binutils и играет ключевую роль в процессе сборки программ на языке C/C++ и других ЯП, поддерживающих создание объектных файлов.
Основная функция команды ld — заключается в том, чтобы связать вместе различные объектные файлы (.o), библиотеки (.a или *.so) и другие компоненты, необходимые для создания конечного исполняемого файла или библиотеки.
Во время этого процесса компоновщик решает ссылки между различными частями программы, такими как функции и переменные, размещает секции данных и кода в памяти и создает итоговую программу.
Основные опции команды ld:
Пример использования.
Предположим, у нас есть два объектных файла main.o и funcs.o, а также библиотека libmath.a. Мы можем создать исполняемый файл следующим образом:
Здесь мы создаем исполняемый файл myprogram, используя объектные файлы main.o и funcs.o, а также подключаем библиотеку libmath.a, находящуюся в каталоге /path/to/libs.
Команда ld — инструмент для управления процессом компиляции и сборки программ в Linux.
Она предоставляет разработчикам гибкость и контроль над тем, как создаются исполняемые файлы и библиотеки, позволяя оптимизировать процесс разработки и настройки программного обеспечения под конкретные нужды.
Команда ld (GNU линкер в Linux) — используется для компоновки объектных файлов в исполняемые файлы или библиотеки.
Она является частью набора инструментов GNU Binutils и играет ключевую роль в процессе сборки программ на языке C/C++ и других ЯП, поддерживающих создание объектных файлов.
Основная функция команды ld — заключается в том, чтобы связать вместе различные объектные файлы (.o), библиотеки (.a или *.so) и другие компоненты, необходимые для создания конечного исполняемого файла или библиотеки.
Во время этого процесса компоновщик решает ссылки между различными частями программы, такими как функции и переменные, размещает секции данных и кода в памяти и создает итоговую программу.
Основные опции команды ld:
-o <output> — определяет имя выходного файла.
Например, -o myprogram;
-L <path> — указывает путь к каталогу, содержащему библиотеки.
Например, -L/usr/local/lib;
-l <library> — подключает библиотеку.
Например, -lm подключит математическую библиотеку libm;
-shared — создает разделяемую библиотеку (.so);
-static — использует статические версии библиотек вместо динамических;
-T <linker_script> — задает файл сценария линковщика, определяющий, как должны быть размещены секции программы в памяти.
Пример использования.
Предположим, у нас есть два объектных файла main.o и funcs.o, а также библиотека libmath.a. Мы можем создать исполняемый файл следующим образом:
$ ld -o myprogram main.o funcs.o -L/path/to/libs -lmath
Здесь мы создаем исполняемый файл myprogram, используя объектные файлы main.o и funcs.o, а также подключаем библиотеку libmath.a, находящуюся в каталоге /path/to/libs.
Команда ld — инструмент для управления процессом компиляции и сборки программ в Linux.
Она предоставляет разработчикам гибкость и контроль над тем, как создаются исполняемые файлы и библиотеки, позволяя оптимизировать процесс разработки и настройки программного обеспечения под конкретные нужды.
#33_ASM
ОСНОВНЫЕ ЧАСТИ ПРОГРАММЫ НА АССЕМБЛЕРЕ (NASM):
section .data
section .bss
section .txt
section .DATA — в разделе section .data объявляются и определяются инициализируемые данные в следующем формате:
<variable name> <type> <value>
Пример:
msg db "Hello, world!",10
msg — имя переменной,
db — тип переменной,
"Hello, world!" — строка сохраняемая в памяти,
10 — ascii код символа новой строки.
Раздел section .data также может содержать константы, т. е. значения, которые невозможно изменить в программе.
Константы определяются в следующем формате:
<constant name> equ <value>
Пример:
pi equ 3.1415926
ОСНОВНЫЕ ЧАСТИ ПРОГРАММЫ НА АССЕМБЛЕРЕ (NASM):
section .data
section .bss
section .txt
section .DATA — в разделе section .data объявляются и определяются инициализируемые данные в следующем формате:
<variable name> <type> <value>
Пример:
msg db "Hello, world!",10
msg — имя переменной,
db — тип переменной,
"Hello, world!" — строка сохраняемая в памяти,
10 — ascii код символа новой строки.
Раздел section .data также может содержать константы, т. е. значения, которые невозможно изменить в программе.
Константы определяются в следующем формате:
<constant name> equ <value>
Пример:
pi equ 3.1415926
#34_ASM
section .BSS
Аббревиатура bss означает Block Started by Symbol (блок, начинающийся с символа) и ведет свое происхождение с 1950-х годов, когда этот блок был компонентом языка ассемблера, разработанного для IBM 704.
В этот раздел помещаются не инициализированные переменные.
Для таких неинициализированных переменных выделяемое пространство памяти объявляется в следующем формате:
<variable name> <type> <number>
Например, следующая инструкция объявляет пространство памяти для массива из 20 двойных слов:
dArray resd 20
section .BSS
Аббревиатура bss означает Block Started by Symbol (блок, начинающийся с символа) и ведет свое происхождение с 1950-х годов, когда этот блок был компонентом языка ассемблера, разработанного для IBM 704.
В этот раздел помещаются не инициализированные переменные.
Для таких неинициализированных переменных выделяемое пространство памяти объявляется в следующем формате:
<variable name> <type> <number>
Например, следующая инструкция объявляет пространство памяти для массива из 20 двойных слов:
dArray resd 20