Практическая работа 8 «РАБОТА С ЭЛЕМЕНТАМИ ОДНОМЕРНОГО МАССИВА» 1. ЦЕЛЬ И СОДЕРЖАНИЕ МЕТОДИЧЕСКИХ УКАЗАНИЙ Целью работы является закрепление теоретических знаний по разделу «архитектура набора команд» компьютера и получение практических навыков в программировании на Ассемблере под 32-разрядную Windows. Краткое содержание. В данной практической работе мы научимся организовывать циклы для обработки одномерных массивов, изучим некоторые виды относительной адресации переменных в памяти. 2. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ Для описания и инициализации массива элементов используются те же директивы, что и для описания единичных переменных. .data A B CC DB DW DD 1,2,3,4,5,6,7,8 ;массив из 8 однобайтовых элементов 1,8,1024,4095 ;массив из 4 двухбайтовых элементов +255,-100 ;массив из 2 четырёхбайтовых элементов В памяти элементы массива располагаются последовательно, начиная с младшего элемента. Если элемент имеет размерность более одного байта, то согласно архитектуре little-endian по младшему адресу храниться младший байт числа. Это значит, что адресом элемента в памяти является адрес его младшего байта. Например, обратите внимание, что элемент В[1], равный 000816 в шестнадцатеричном представлении, храниться в памяти перевёрнутым как два байта 08 00 с последовательными адресами 0040300А и 0040300В. Для обращения к элементу одномерного массива требуется составить формулу для вычисления его адреса в памяти. Имя массива однозначно определяет адрес его нулевого элемента. Этот адрес можно предварительно загрузить в один из регистров, и затем использовать косвенно-регистровую адресацию. ESI,СС ;в регистр ESI заноситься адрес младшего байта нулевого ; элемента массива СС Аналогично работает команда LEA MOV ESI,offset СС ;ESI= адрес мл. байта нулевого элемента массива СС Если к этой величине прибавить размер элемента в байтах то получим адрес следующего элемента, и так далее. ADD ESI,4 ;увеличение адреса на 4 Для обращения за элементом в ОП по этому адресу надо записать следующую формулу: MOV EAX,[ESI] ;косвенно-регистровая адресация элемента массива CC ;EAX=содержимое ячейки ОП по адресу [ESI], ; размером 32 бит (как и регистр EАХ) MOV AX , [ESI] РП ОП ЕAX … ESI операнд Или другой вариант MOV MOV ESI,0 ;ESI=0 AX,A[ESI] ;AX= ОП [ESI,15÷0] Для того, чтобы перебрать все элементы массива, требуется организовать цикл с количеством проходов, равным количеству элементов массива (аналогично конструкции for в Си, Паскале). Счётчиком цикла по умолчанию всегда является регистр ЕСХ. Если в него поместить величину, равную числу элементов, то по команде организации цикла в конце каждого цикла из регистра ЕСХ вычитается «1» и получившееся значение сравнивается с «0». Когда ЕСХ=0, цикл заканчивается, иначе организуется переход на начало цикла. Цикл while организуется с помощью команд условного перехода. Далее приведён фрагмент кода программы, которая сортирует одномерный массив по возрастанию методом пузырька. Этот метод подразумевает несколько переборов всех элементов. В каждом переборе происходит многократное попарное сравнение всех соседних элементов массива. Перед началом каждого перебора флаг перестановки сбрасывается (становиться равным «0»). Если встречаются неупорядоченные пары, то элементы пары меняются местами и устанавливается флаг необходимости провести ещё один перебор. Процедура перебора повторяется до тех пор, пока флаг перестановки равен «1». Если после очередного перебора флаг остаётся нулевым, то сортировка заканчивается. ;стандартное начало программы .data A DW 0,1,2,4,6,7,3 ;массив двухбайтовых элементов … .code … WHILE1: FOR1: NEXT: MOV DL,1 MOV ECX,7-1 MOV DL,0 LEA ESI,A MOV AX,[ESI] MOV BX,[ESI+2] CMP AX,BX JBE NEXT MOV [ESI],BX MOV [ESI+2],AX OR DH,1 INC ESI INC ESI LOOP FOR1 OR DH,0 JNZ WHILE1 ;флаг перестановок установить в «1» для первичного входа в цикл перебора ;начало цикла while ;сброс флага ;загрузка в регистр ESI адреса массива (нулевого элемента) ;загрузка в регистр АХ очередного элемента массива с адресом ESI ;загрузка в рег. ВХ след. по порядку элемента с адресом ESI+длина элемента (2) ;сравнение пары элементов ;АХ≤ВХ тогда переход к следующей паре ; перестановка ; ;установка флага ;вычисление адреса нового элемента для перебора ESI=ESI+длина эл-та ;команда организации цикла попарных перестановок (со счётчиком ЕСХ) ;проверка флага ;на начало цикла перебора «пока флаг≠0» (без счётчика) ;вывод результатов ;стандартное завершение работы программы 1. 2. 3. 4. 3. ЗАДАНИЕ Создать свою программу prakt8.asm согласно варианту в редакторе Quick Editor пакета MASM, которая выполняет заданные действия, выводит на экран окно с результатами. Откомпилировать программу и запустить на исполнение (в случае безошибочной компиляции, иначе исправить синтаксические ошибки и провести повторную компиляцию и запуск). Отладить программу через OllyDbg, проследить изменения в регистрах. Ответить на вопросы для самопроверки. 4. ВАРИАНТЫ ЗАДАНИЙ № вар 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Задание (целочисленные операции) Найти минимальный и максимальный элемент массива и запомнить их номера, предусмотреть случай, когда все/несколько элементов равны. Найти нулевой/ые элементы массива и запомнить их номера, предусмотреть случай, когда таких элементов нет. Найти элементы массива, содержащие 2 единицы в двоичном представлении и запомнить их номера, предусмотреть случай, когда таких элементов нет. Поменять местами элементы с заданными номерами и с заданными значениями, предусмотреть случай, когда таких элементов нет. Умножить каждый элемент массива на его номер. Вычислить сумму всех элементов массива и запомнить её в заданной переменной. Вычислить сумму всех отрицательных элементов массива и запомнить её в заданной переменной, предусмотреть случай, когда таких элементов нет. Вычислить сумму всех элементов массива больше заданного числа и запомнить её в заданной переменной, предусмотреть случай, когда таких элементов нет. Вычислить сумму всех чётных элементов массива и запомнить её в заданной переменной, предусмотреть случай, когда таких элементов нет. Поменять местами элементы с чётными и нечётными номерами, предусмотреть случай, когда общее число элементов массива чётно и нечётно. Поменять местами первый и последний элементы массива, второй и предпоследний, и т.д. предусмотреть случай, когда общее число элементов массива чётно и нечётно. Поменять местами элементы массива, с произвольными номерами (заданы как переменные в памяти), предусмотреть случай, когда эти номера больше общего числа элементов массива. 4 5. КОНТРОЛЬНЫЕ ВОПРОСЫ 1. Как располагаются элементы массива в памяти компьютера? 2. Как рассчитать адрес элемента с произвольным номером? 3. Как организовать цикл для перебора всех элементов массива? 4. Как организуется счётчик циклов? 5. Как изменяется номер и адрес элемента массива в цикле? 6. СПИСОК ЛИТЕРАТУРЫ 1. Нарваха Р. Введение в крэкинг с нуля, используя OllyDbg. (http://pro.dtn.ru/cr.html). 2. Intel 64 and IA32-Architectures Software Developers Manual (с сайта intel.com) 3. Гук М., Юров В. Процессоры Pentium III, Athlon и другие. – СПб.: Издательство «Питер», 2000. 4. Юров В. Ассемблер. – СПб.: Издательство «Питер», 2002. 5. Иванова Е.М. «Форматированный вывод числа – результата вычислений программы». Учебно-методическое пособие. Москва – МИЭМ ВШЭ, 2013. 5