Skip to content

Latest commit

 

History

History
207 lines (140 loc) · 21.4 KB

lab03_listing.textile

File metadata and controls

207 lines (140 loc) · 21.4 KB

Лабораторная работа №3. Работа с файлом листинга

Краткие теоретические сведения

Системные инструменты

Права доступа к файлам

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

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

chown [ключи] <новый_пользователь>[:новая_группа] <файл>

или

chgrp [ключи] < новая_группа > <файл>

Набор прав доступа задается тройками битов и состоит из прав на чтение, запись и исполнение файла. В символьном представлении он выглядит как строка rwx, где вместо любого символа может стоять дефис. Буква означает наличие права (установлен в единицу второй бит триады r — чтение, первый бит w - запись, нулевой бит х - исполнение), а дефис означает отсутствие права (нулевое значение соответствующего бита). Очевидно, что эти три бита могут быть записаны еще и как восьмеричное число. Так, права доступа r-х (чтение и исполнение без записи) понимаются как три двоичные цифры 101 или как восьмеричная цифра 5. Численное представление прав доступа называется абсолютным, или двоичной маской.

Полная строка прав доступа в символьном представлении устроена так:

<права_владельца><права_группы><права_остальных>

В абсолютном представлении права владельца являются старшей цифрой восьмеричного числа, права группы - средней
и права остальных -
младшей. Так, права rwxr-x--x выглядят как двоичное число 111 101 001, или восьмеричное 751.

Команда изменения прав доступа chmod понимает как абсолютное, так и символьное указание прав.

Свойства (атрибуты) файлов и каталогов можно вывести на терминал с помощью команды ls с ключом -l:

$ls -I /home/debugger/README
-rwxr-xr-- 1 debugger users 0 Feb 14 19:08 /home/debugger/README

Назначим файлу /home/debugger/README права rw-r, то есть разрешим себе чтение и запись, группе только чтение, остальным пользователям — ничего:

$cd ~ # переход в свой домашний каталог
$chmod 640 README # 110 100 000 == 640
$ls -1 README
-rw-r 1 debugger users 0 Feb 14 19:08 /home/debugger/README

В символьном представлении можно явно указывать, кому какое право мы хотим добавить, отнять или присвоить. Добавим право на исполнение файла README группе и всем остальным:

$chmod go+x README
$ls -1 README
-rw-r-x--x 1 debugger users 0 Feb 14 19:08 /home/debugger/README

Формат символьного режима:

chmod <категория><действие><набор_прав>< файл >

Возможные значения аргументов команды представлены в таблице:

|l|l|l|

& Значение
Категория & u & Владелец
  & g & Группа владельца
  & о & Прочие
  & а & Все пользователи, то есть «а» эквивалентно «ugo»
Действие & + & Добавить набор прав
  & – & Отменить набор прав
  & = & Назначить набор прав
Право & r & Право на чтение
  & w & Право на запись
  & x & Право на исполнение
  & s & Право смены идентификатора пользователя или группы
  & t & Бит прилипчивости (sticky-бит)
  & u & Такие же права, как у владельца
  & g & Такие же права, как у группы
  & о & Такие же права, как у прочих

Название бита прилипчивости унаследовано от тех времен, когда объем оперативной памяти был маленьким, а процесс подкачки медленным. Этот бит позволял оставлять небольшие часто используемые программы в памяти для ускорения их запуска. Сейчас его значение переосмыслено: этот бит, установленный для каталога, приводит к тому, что удалять файлы из этого каталога могут только владелец файла и владелец каталога. Обычно это используется в каталогах, открытых для записи всем (например, /tmp).

Права смены пользователя и группы (SUID-бит и SGID-бит) означают следующее. Обычно исполняемый файл (программа или командный сценарий) получает те же права на доступ к файлам, что и пользователь, который запустил его на выполнение. Но у этого файла есть еще и владелец, полномочия которого могут быть совсем другими. Наличие одного из этих битов позволяет выполняющейся программе пользоваться полномочиями владельца программного файла или члена его группы.

Назначение файла листинга

Листинг — это один из выходных файлов, создаваемых транслятором. Он имеет текстовый вид и нужен при отладке программы, т. к. кроме строк самой программы содержит дополнительную информацию.

Обычно nasm создает в результате ассемблирования только объектный файл. Получить файл листинга можно, указав ключ -l и задав имя файла листинга в командной строке. Например:

nasm -l main.lst main.asm

Рассмотрим фрагмент файла листинга.

1           BITS32 ; Говорим компилятору, что код 32-битный
2                   section .data
3 00000000 48656C6C6F20776F72- hello:     db 'Hello world!',10
4 00000009 6C64210A
5                   helloLen:  equ $-hello ; Длина строки
6
7                      section .text
8                      global _start
9   ; чтобы линкер смог метку найти и сделать точкой входа в программу.
10
11              start:
12 00000000 B804000000 mov eax,4 ; Системный вызов для записи (sys_write)
13 00000005 BB01000000  mov ebx,1 ; Описатель файла 1 - стандартный вывод
14 0000000A B9[00000000] mov ecx,hello ; Адрес строки hello в ecx
15 0000000F BA0D000000   mov edx,helloLen ; helloLen - это константа
16     ;  mov edx,[helloLen] для получения действительного значения
17 00000014 CD80       int 80h     ; Вызов ядра
18
19 00000016 B801000000  mov eax,1  ; Системный вызов для выхода (sys_exit)
20 0000001B BB00000000  mov ebx,0  ; Выход с кодом возврата 0 (без ошибок)
21 00000020 CD80    int 80h    ; Вывозов ядра

Структура листинга

Строки в первой части листинга имеют следующую структуру (рис. [pic:l3]):

[ht] [pic:l3]

Все ошибки и предупреждения, обнаруженные при ассемблировании, транслятор выводит на экран и файл листинга не создается.

  • «Номер строки» представляет собой номер строки файла листинга. Номера строк особенно полезны при работе с перекрестными ссылками. Учтите, что номера строк в поле «номер строки» — это не номера строк исходного модуля. Например, при расширении макрокоманды или включении файла отсчет строк продолжается, хотя текущая строка в исходном файле остается той же. Чтобы перевести номер строки (сгенерированный, например, при создании перекрестных ссылок), вы должны найти соответствующую строку в листинге, а затем (по номеру или на глаз) найти ее в исходном файле.
  • «Адрес» — это смещение машинного кода от начала текущего сегмента.
  • «Машинный код» представляет собой действительную последовательность шестнадцатеричного значения байт и слов, которые ассемблируются из соответствующей исходной строки программы. Например, инструкция int 80h начинается по смещению 00000014 в сегменте кода. Информация справа от данной инструкции - это машинный код, в который ассемблируется инструкция, то есть инструкция int 80h ассемблируется в CD80 (в шестнадцатеричном представлении). CD80 - это инструкция на машинном языке, вызывающая прерывание ядра.
  • Наконец, поле «исходный текст программы» — это просто строка исходной программы вместе с комментариями. Некоторые строки на языке ассемблера (например, строки, содержащие только комментарии) не генерируют никакого машинного кода, и поля «смещение» и «исходный текст программы» в таких строках отсутствуют. Тем не менее номер строки им присваивается.

Допустимыми символами в метках являются буквы, цифры, _, $, #, </tt>, @~, ., и ?. Начинаться метка или идентификатор могут с буквы, ., _ и ?. Перед идентификаторами, которые пишутся как зарезервированные слова нужно писать $, чтобы компилятора трактовал его верно. Максимальная длина идентификатора 4095 символов.

Элементы программирования

Описание инструкции вычитания

Схема команды целочисленного вычитания sub выглядит следующим образом:

sub операнд_1, операнд_2

работы команды включает два действия:

  • выполнить вычитание: операнд_1 = операнд_1 - операнд_2;
  • установить флаги.

Флаги, устанавливаемые командой, подробнее рассматриваются ниже.

Команды условного перехода

Все машинные команды условного перехода, кроме одной, вычисляют условие перехода, анализируя один, два или три флага из регистра флагов, и лишь одна команда условного перехода вычисляет условие перехода, анализируя значение регистра CX. Команда условного перехода в языке Ассемблер имеет вид

j<мнемоника перехода> i8

Мнемоника перехода (от одной до трёх букв) связана со значением анализируемых флагов (или регистра CX), либо со способом формирования этих флагов. Чаще всего программисты формируют флаги, проверяя отношение между двумя операндами op1 <отношение> op2, для чего выполняется команда вычитания или команда сравнения. Команда сравнения имеет мнемонический код операции cmp и такой же формат, как и команда вычитания:

cmp op1,op2

Она и выполняется точно так же, как команда вычитания — за исключением того, что разность не записывается на место первого операнда. Таким образом, единственным результатом команды сравнения является формирование флагов, которые устанавливаются так же, как и при выполнении команды вычитания.

Программист по своему желанию может трактовать результат вычитания (сравнения) как производимый над знаковыми или же беззнаковыми числами. От этой трактовки может зависеть, будет ли один операнд считаться большим, чем другой, или же нет. Так, например, рассмотрим два коротких целых числа 0FFh и 01h — с учетом того, что отрицательные числа представляются процессором в дополнительном коде. Если числа знаковые, 0FFh = -1 < 01h = 1, а если беззнаковые, то 0FFh = 255 > 01h = 1.

Инструкции условной передачи управления бывают следующими:

Мнемокод условие перехода  
  Флаги Смысл
ja/jnbe CF or ZF=0 выше /не ниже и не равно
jae/jnb CF=0 выше или равно/не ниже
jb/jnae CF=1 ниже/не выше и не равно
jbe/jna CF or ZF=1 ниже или равно/не выше
je/jz ZF=1 равно/нуль
jne/jnz ZF=0 не равно/не нуль
jg/jnle (SF xor OF) or ZF=0 больше/не меньше и не равно
jge/jnl SF xor OF=0 больше или равно/не меньше
jl/jnge (SF xor OF)=1 меньше/не больше и не равно
jle/jng ((SF xor OF) or ZF)=1 меньше или равно/не больше
jp/jpe PF=1 есть паритет/паритет четный
jnp/jpo PF=0 нет паритета/паритет нечетный
jc CF=1 перенос
jnc CF=0 нет переноса
jo OF=1 переполнение
jno OF=0 нет переполнения
jns SF=0 знак +
js SF=1 знак -

Мнемоники, идентичные по своему действию, написаны в таблице через дробь (например, ja и jnbe). Программист выбирает, какую из них применить, чтобы получить более простой для понимания текст программы.

Примечание: термины «выше» («a» от англ. «above») и «ниже» («b» от англ. «below»)применимы для сравнения беззнаковых величин (адресов), а термины «больше» («g» от англ. «greater») и «меньше» («l» от англ. «lower») используются при учете знака числа. Таким образом, мнемонику инструкции ja/jnbe можно расшифровать как «jump (переход) if above (если выше) / if not below equal (если не меньше или равно)».

Задание для выполнения

  1. Написать программу, работающую по следующему алгоритму:
    • вывести на экран запрос о времени дня, например, «Полдень прошел?»;
    • принять с клавиатуры ответ (Y/N);
    • если было введено N выдать сообщение «Доброе утро», в противном слу- чае — «Добрый день».
  2. Получить файл листинга и внимательно ознакомиться с его форматом и содержимым.
  3. В любой инструкции с двумя операндами удалить один операнд и проассемблировать программу с получением файла листинга. Какие выходные файлы создаются в этом случае? Что добавляется в листинге?
  4. Подробно объяснить содержимое трех строк файла листинга по выбору.
  5. Получить имя владельца и числовой код прав доступа для файлов, сгенерированных в результате выполнения работы. Расшифровать права доступа.
  6. Изменить права доступа к исполняемому файлу, запретив его выполнение. Попытаться выполнить файл.
  7. Разрешить выполнение исходного текста программы как исполняемого файла. Попытаться выполнить его и объяснить результат.

Контрольные вопросы

  1. Каким образом в Unix-подобных ОС определяются права доступа к файлу?
  2. Как ОС определяет, является ли файл исполняемым? Как регулировать права на чтение и запись?
  3. Как разграничить права доступа для различных категорий пользователей?
  4. Для чего нужен файл листинга? В чем его отличие от текста программы?
  5. Каков формат файла листинга? Из каких частей он состоит? Каково назначение первой части?
  6. Как в программах на ассемблере можно выполнить ветвление?