Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная 6.docx
Скачиваний:
9
Добавлен:
18.07.2022
Размер:
40.64 Кб
Скачать

Санкт-Петербургский политехнический университет Петра Великого

Институт компьютерных наук и технологий

Высшая школа интеллектуальных систем и суперкомпьютерных технологий лабораторная работа №6 «Команды и способы адресации для x86 в 32-битном режиме»

по дисциплине «Архитектура вычислительных систем»

Выполнил

студент гр. 3530903/80001 А. В. Шильникова

Руководитель Н. М. Вербова

«___» __________ 2020 г.

Санкт-Петербург

2020

Цель работы: познакомиться с системой процессорных команд и способами использования этих команд.

Задачи:

• взять фрагмент программы на языке Си, заданный преподавателем, или написать такой фрагмент самостоятельно по заданной спецификации;

• оттранслировать программу, содержащую этот фрагмент;

• перейти в режим отладки и изучить дизассемблированный код фрагмента;

• самостоятельно заменить обращение к элементам массива через индекс на обращение через указатель, перетранслировать программу;

• проанализировать и прокомментировать (описать), как компилятор реализовал обращение через указатель.

Вариант 6

1-6.

short Mas[10];

unsigned long i;

void main() {

i = 9;

while (i > 0) {

if ((i >= 3) && (i != 5))

Mas[i] = (3 * i) ^ 0x18;

else

Mas[i] = (27 * i) / 8;

i--;

}

}

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

1: short Mas[10];

2: unsigned long i;

3: void main() { //вызов функции main()

00D81750 55 push ebp //сохраняем значение регистра ebp в стек, чтобы после выполнения программы или подпрограммы frame pointer можно было вернуть в состояние до вызова функции. Тип адресации - неявная

00D81751 8B EC mov ebp,esp //в регистр ebp копируется значение из регистра esp. Тип адресации - регистровая

00D81753 81 EC C0 00 00 00 sub esp,0C0h //отнимаем от esp OCOh и сохраняем результат в esp. Выделяем память для переменных. Тип адресации источника – непосредственная, приемника - регистровая

00D81759 53 push ebx

00D8175A 56 push esi

00D8175B 57 push edi //сохраняем в стек значения регистров ebx, esi, edi. Тип адресации - неявная

00D8175C 8D BD 40 FF FF FF lea edi,[ebp-0C0h] //сохраняем в edi значение ebp-OCOh. Тип адресации источника – косвенно-регистровая со смещением (-OCOh), приемника – регистровая.

00D81762 B9 30 00 00 00 mov ecx,30h //записываем в регистр ecx значение 30h. Регистр ecx применяют для организации циклов. Перед началом цикла в него помещают количество итераций. Каждая команда loop уменьшает значение этого регистра. Тип адресации источника – непосредственная, приемника – регистровая.

00D81767 B8 CC CC CC CC mov eax,0CCCCCCCCh //записываем в регистр eax значение 0CCCCCCCCh, которое означает, что оно не инициализировано. Тип адресации источника – непосредственная, приемника – регистровая.

00D8176C F3 AB rep stos dword ptr es:[edi] //rep – префикс, позволяющий выполнить команду stos определенное количество раз, указанных в ecx. Происходит циклический повтор инициализации массива (выполнение команды по адресу es:[edi]

4: i = 9;

00D81778 C7 05 4C A1 D8 00 09 00 00 00 mov dword ptr [i (0D8A14Ch)],9 //записываем в переменную i по адресу 0D8A14Ch значение 9. dword ptr означает, что размер i составляет 32 бита, что соответствует размеру, занимаемому в памяти переменной типа long. Тип адресации источника – непосредственная, приемника - абсолютная

5: while (i > 0) {

00D81782 83 3D 4C A1 D8 00 00 cmp dword ptr [i (0D8A14Ch)],0 //сравниваем значение счетчика i по адресу 0D8A14Ch со значением 0, то есть проверяем условие цикла while. dword ptr означает, что размер i составляет 32 бита, что соответствует размеру, занимаемому в памяти переменной типа long. Тип адресации источника – непосредственная, приемника - абсолютная

00D81789 76 53 jbe main+8Eh (0D817DEh) //обрабатываем эту строку, когда в результат выставляются флаги, гарантирующие заход в jbe, т.е. когда i будет меньше или равен нулю. В этом случае выходим из цикла (совершается jmp в адрес 0D817DEh, который указывает на первую из команд для выхода из подпрограммы). Тип адресации – абсолютная, путем смещения относительно процедуры main.

6: if ((i >= 3) && (i != 5))

00D8178B 83 3D 4C A1 D8 00 03 cmp dword ptr [i (0D8A14Ch)],3

00D81792 72 23 jb main+67h (0D817B7h) //сравниваем значение счетчика i по адресу 0D8A14Ch со значением 3, если i больше 3 (jb), то происходит jmp на строку с адресом 0D817B7h, которая соответствует выполнению действия else. Тип адресации источника – непосредственная, приемника – абсолютная. Во второй строке тип адресации – абсолютная, путем смещения относительно процедуры main

00D81794 83 3D 4C A1 D8 00 05 cmp dword ptr [i (0D8A14Ch)],5

00D8179B 74 1A je main+67h (0D817B7h) //сравниваем значение счетчика i по адресу 0D8A14Ch со значением 5, на неравенство (je). Тип адресации источника – непосредственная, приемника – абсолютная. Во второй строке тип адресации – абсолютная, путем смещения относительно процедуры main

7: Mas[i] = (3 * i) ^ 0x18;

00D8179D 6B 05 4C A1 D8 00 03 imul eax,dword ptr [i (0D8A14Ch)],3 //Если оба условия выполнились выполняем действие. Умножаем значение счетчика i на 3 и записываем результат в регистр eax. imul – перемножение знаковых чисел. Тип адресации источник 1 – непосредственная, источник2 – абсолютная, приемник - регистровая

00D817A4 83 F0 18 xor eax,18h //производим поразрядное исключающее «или» eax с константой 0x18 и записываем в регистр eax. Тип адресации источника – непосредственная, приемник - регистровая

00D817A7 8B 0D 4C A1 D8 00 mov ecx,dword ptr [i (0D8A14Ch)] //загружаем в ecx значение переменной i. Тип адресации источника – абсолютная, приемника - регистровая

00D817AD 66 89 04 4D 38 A1 D8 00 mov word ptr Mas (0D8A138h)[ecx*2],ax //записываем в ячейку массива Mas с индексом ecx (значение i). Нужная ячейка выбирается сдвигом на i*2 байт. Тип адресации источника – регистровая, приемника – регистровая.

00D817B5 EB 18 jmp main+7Fh (0D817CFh) //переход на строку с адресом 0D817CFh. Тип адресации – абсолютная, путем смещения относительно процедуры main

8: else

9: Mas[i] = (27 * i) / 8;

00D817B7 6B 05 4C A1 D8 00 1B imul eax,dword ptr [i (0D8A14Ch)],1Bh //если хотя бы одно из условий в if не выполнилось, то выполняем это действие. Умножаем значение счетчика i на 27 и записываем результат в регистр eax. Тип адресации источника 18h – непосредственная, источника i – абсолютная, приемника - регистровая

00D817BE C1 E8 03 shr eax,3 //Логический сдвиг вправо eax на 3

00D817C1 8B 0D 4C A1 D8 00 mov ecx,dword ptr [i (0D8A14Ch)] //Записываем в переменную ecx значение i. Тип адресации источника – абсолютная, приемника – регистровая.

00D817C7 66 89 04 4D 38 A1 D8 00 mov word ptr Mas (0D8A138h)[ecx*2],ax //заносим в память младшие два байта результата Mas[i] = ax. Тип адресации источника – абсолютная, приемника – регистровая.

10: i--;

00D817CF A1 4C A1 D8 00 mov eax,dword ptr [i (0D8A14Ch)] //заносим в eax значение адреса переменной i. Тип адресации источника – абсолютная, приемника - регистровая

00D817D4 83 E8 01 sub eax,1 //вычитаем из eax единицу. Тип адресации источника – непосредственная, приемника - регистровая

00D817D7 A3 4C A1 D8 00 mov dword ptr [i (0D8A14Ch)],eax //записываем в переменную i значение eax. Тип адресации источника – регистровая, приемника - абсолютная

11: }

00D817DC EB A4 jmp main+32h (0D81782h) //возвращаемся к началу цикла и проверяем условие захода в него. Тип адресации – абсолютная, путем смещения относительно процедуры main

12: }

00D817DE 33 C0 xor eax,eax //обнуляем значение eax. Тип адресации - регистровая

00D817E0 5F pop edi //тип адресации - регистровая

00D817E1 5E pop esi //тип адресации - регистровая

00D817E2 5B pop ebx //тип адресации - регистровая

00D817E3 81 C4 C0 00 00 00 add esp,0C0h //тип адресации источника – непосредственная, приемника - регистровая

00D817E9 3B EC cmp ebp,esp //тип адресации - регистровая

00D817EB E8 40 FA FF FF call __RTC_CheckEsp (0D81230h)

00D817F0 8B E5 mov esp,ebp //тип адресации - регистровая

00D817F2 5D pop ebp //возвращаем значения переменных edi, esi, ebx, esp, ebp до момента начала выполнения программы

00D817F3 C3 ret //завершение выполнение программы

Адреса переменных в памяти:

i

0D8A14Ch

Mac[0]

0D8A138h

Mac[1]

0D8A13Ch

Mac[2]

0D8A140h

Mac[3]

0D8A144h

Mac[4]

0D8A148h

Mac[5]

OD8A14Ch

Mac[6]

0D8A150h

Mac[7]

0D8A154h

Mac[8]

0D8A158h

Mac[9]

0D8A15Ch

Программа с доступом к элементам массива через указатели:

short *Mas[10];

unsigned long i;