- •Лекция №1. Основные понятия. Первая программа для dos и под Windows. Представление данных в компьютере.
- •Сам ассемблер — программа, которая переводит текст с языка, понятного человеку, в язык, понятный процессору, получает объектный модуль;
- •Компоновщик (linker), который создает исполнимые файлы из одного или нескольких объектных модулей, полученных после запуска ассемблера;
- •Дополнительные вспомогательные программы — компиляторы ресурсов, расширители dos и тому подобное (см. Табл.).
- •Написать её в блокноте, сохранять в *.Asm файл;
- •Из командной строки вызвать ассемблер tasm32.Exe (tasm.Exe);
- •Из командной строки вызвать линковщик tlink32.Exe (tlink.Exe);
- •Процессоры и их регистры
- •Процессоры x86
- •Регистры процессора
- •Описание регистров
- •Задача: найти старшую часть расширенного регистра (eax, ebx, ..., esi, edi)?
- •0030:4012 (Всё шестнадцатиричное)
- •4) Нельзя использовать сегментный регистр cs в качестве операнда назначения.
- •5) Оператор ptr можно применять и когда требуется принудительно поменять размерность операндов. К примеру, требуется переслать значение 0ffh во второй байт поля flp:
- •Xchg eax,ebx ; обменять содержимое регистров eax и ebx.
- •Xchg al,al ; а эта команда не делает ничего
- •Xchg ax, word ptr [si] ; обменять содержимое регистра ах и слова в памяти по адресу в [si].
- •Технология sse. Блок xmm
- •Имеются специальные команды сравнения двух вещественных чисел. После их выполнения формируются и помещаются в eflags признаки, характеризующие результат операции.
- •8 Флагов состояния. Эти флаги могут изменяться после выполнения машинных команд;
- •1) Первой известной кодировкой символов была кодировка ascii, и она используется до сих пор. В ascii-кодировке каждый символ занимает 8 бит, или один байт.
- •2. Адресные операнды – задают физическое расположение операнда в памяти с помощью указания двух составляющих адреса: сегмента и смещения. К примеру:
- •6. Структурные операнды используются для доступа к конкретному элементу структуры.
- •7. Записи (аналогично структурному типу) используются для доступа к битовому полю некоторой записи.
- •Команды безусловной передачи управления:
- •Команды условной передачи управления:
- •Команды управления циклом:
- •Лекция № 4. Условные переходы. Арифметиченские команды. Bcd числа.
- •1111111011101101 Инвертируем 0000000100010010
- •Лекция №5. Арифметические команды над целыми числами (продолжение). Арифметические операции над двоично-десятичными числами (bcd числами)
- •К содержимому младшей тетрады al прибавляется 6;
- •Флаг cf устанавливается в 1, тем самым фиксируется перенос в старший разряд для того, чтобы его можно было учесть в последующих действиях.
- •Из содержимого младшей тетрады регистра al вычитается 6;
- •Обнуляется старшая тетраду регистра al;
- •Устанавливает флаг cf в 1, фиксируя воображаемый заём из старшего разряда.
- •Делит ax на 10;
- •Результат деления записывается так: частное – в ah, остаток в al.
- •1) Преобразует двузначное неупакованное bcd-число в регистре ах в двоичное число;
- •2) Полученное двоичное число используется в качестве делимого в операции деления;
- •3) Полученное двоичное число помещается в регистр aх.
- •Деление с остатком
- •Блок-схема вывода результата при делении с остатком Числа с плавающей запятой. Работа с сопроцессором
- •Число имеет вид 1,1100011 × 2-1 или 0,11100011.
- •Переводом в десятичную систему счисления получаем 0,88671875. Лекция №6. Работа с сопроцессором. Команды для работы с fpu. Работа с fpu.
- •Блок-схема вывода на экран вещественного числа, которое хранится в регистре st(0) сопроцессора.
- •Деление с остатком, используя команды целочисленного деления
- •Блок-схема вывода результата при делении с остатком Трансцендентные операции fpu
- •Массивы
- •Перечислением элементов массива в поле операндов одной из директив описания данных. Например:
- •Используя оператор повторения dup. К примеру:
- •4) Mov esi,6*2 ; 2 байта – размер элементов
- •Индексная адресация со смещением — режим адресации, при котором полный адрес формируется из двух компонентов:
- •Базовая индексная адресация со смещением — режим адресации, при котором полный адрес формируется максимум из трех компонентов:
- •Структуры
- •Организовать обращение к элементам структуры.
- •Цепочечные команды или команды обработки строк символов
- •Организация обращения к элементам записи.
- •Iotest record
- •Работа с записями
- •1) Для выделения элемента записи необходимо:
- •2) Чтобы поместить измененный элемент на его место в запись необходимо:
- •3. В конце работы файл следует закрыть.
- •4. Признаком ошибки при выполнении функции dos является взведенный флаг с (переноса).
- •2. Создание файла с усечением существующего до нулевой длины.
- •LpFileName — указатель на asciiz-строку с именем (путем) открываемого или создаваемого файла;
- •DwDesiredAccess — тип доступа к файлу:
- •4) Mov esi,6*2 ; 2 байта – размер элементов
- •Индексная адресация со смещением — режим адресации, при котором полный адрес формируется из двух компонентов:
- •Базовая индексная адресация со смещением — режим адресации, при котором полный адрес формируется максимум из трех компонентов:
- •Структуры
- •Организовать обращение к элементам структуры.
- •Цепочечные команды или команды обработки строк символов
- •Организация обращения к элементам записи.
- •Iotest record
- •Работа с записями
- •1) Для выделения элемента записи необходимо:
- •2) Чтобы поместить измененный элемент на его место в запись необходимо:
- •3. В конце работы файл следует закрыть.
- •4. Признаком ошибки при выполнении функции dos является взведенный флаг с (переноса).
- •2. Создание файла с усечением существующего до нулевой длины.
- •LpFileName — указатель на asciiz-строку с именем (путем) открываемого или создаваемого файла;
- •DwDesiredAccess — тип доступа к файлу:
- •3) Создать и открыть новый файл
- •4) Чтение из файла или устройства
- •5) Переместить указатель чтения/записи
- •1) HFile – хэндл того файла, в котором перемещается указатель.
- •7) Запись в файл или устройство
- •8) Закрыть файл
- •9) Удаление файла
- •Функция 01h – ожидание ввода символа с эхопечатью
- •Функция 0ah – получение строки символов
- •1) Создать каталог
- •2) Удалить каталог
- •5) Определить текущий каталог
- •Перечень функций прерывания 21h, работающих с файлами, которые имеют длинные имена и соответствующие функции api Win32.
- •Перечислим функции api Win32, имеющие отношение к работе с файловой системой.
- •1) В Win32 получить время создания, время последнего доступа и время последней модификации файла можно с помощью функции GetFileTime.
- •3) В Win32 имеется функция GetFileInformationByHandle, с помощью которой можно получить все атрибуты файла:
- •Int 10h ; вызов прерывания bios
- •Основные графические режимы vga
- •Int 10h ; считываем символ и его атрибут
- •Стандартные цветовые палитры в режимах 4,5,6.
- •02H/03h - Чтение/запись секторов.
- •Прямое программирование видеобуфера в текстовом режиме
- •Лекция №6. Работа с сопроцессором. Команды для работы с fpu. Работа с fpu.
- •Лабораторная работа №12. Тема: Графические видеорежимы. Работа с vga-режимами
- •Лабораторная работа № 8. Тема: Работа с файлами
- •Лабораторная работа №5. Тема: Работа с массивами
- •Лекция №1. Основные понятия. Первая программа для dos и под Windows. Представление данных в компьютере.
- •Сам ассемблер — программа, которая переводит текст с языка, понятного человеку, в язык, понятный процессору, получает объектный модуль;
- •Компоновщик (linker), который создает исполнимые файлы из одного или нескольких объектных модулей, полученных после запуска ассемблера;
- •Дополнительные вспомогательные программы — компиляторы ресурсов, расширители dos и тому подобное (см. Табл.).
- •Написать её в блокноте, сохранять в *.Asm файл;
- •Из командной строки вызвать ассемблер tasm32.Exe (tasm.Exe);
- •Из командной строки вызвать линковщик tlink32.Exe (tlink.Exe);
- •Процессоры и их регистры
- •Процессоры x86
- •Регистры процессора
- •Описание регистров
- •Задача: найти старшую часть расширенного регистра (eax, ebx, ..., esi, edi)?
- •0030:4012 (Всё шестнадцатиричное)
- •4) Нельзя использовать сегментный регистр cs в качестве операнда назначения.
- •5) Оператор ptr можно применять и когда требуется принудительно поменять размерность операндов. К примеру, требуется переслать значение 0ffh во второй байт поля flp:
- •Xchg eax,ebx ; обменять содержимое регистров eax и ebx.
- •Xchg al,al ; а эта команда не делает ничего
- •Xchg ax, word ptr [si] ; обменять содержимое регистра ах и слова в памяти по адресу в [si].
- •Технология sse. Блок xmm
- •Имеются специальные команды сравнения двух вещественных чисел. После их выполнения формируются и помещаются в eflags признаки, характеризующие результат операции.
- •8 Флагов состояния. Эти флаги могут изменяться после выполнения машинных команд;
- •1) Первой известной кодировкой символов была кодировка ascii, и она используется до сих пор. В ascii-кодировке каждый символ занимает 8 бит, или один байт.
- •2. Адресные операнды – задают физическое расположение операнда в памяти с помощью указания двух составляющих адреса: сегмента и смещения. К примеру:
- •5. Структурные операнды используются для доступа к конкретному элементу структуры.
- •6. Записи (аналогично структурному типу) используются для доступа к битовому полю некоторой записи.
- •Команды безусловной передачи управления:
- •Команды условной передачи управления:
- •Команды управления циклом:
- •От типа операнда в команде безусловного перехода (ближний или дальний);
- •Лабораторная работа №1. Тема: знакомство с системой программирования Турбо-ассемблер.
- •1) Пересылка данных
- •2) Xor логическое исключающее или
- •3) Команды передачи управления
- •Задание для самостоятельной работы
- •Лабораторная работа №1. Тема: знакомство с системой программирования Турбо-ассемблер.
- •1) Пересылка данных
- •2) Xor логическое исключающее или
- •3) Команды передачи управления
- •Команды вычитания.
- •Команды умножения.
- •Команда деления
- •Команды преобразования
- •Команды сдвига
- •Задание для самостоятельной работы.
- •Лабораторная работа №4. Тема: перевод чисел из шестнадцатиричной системы исчисления в десятичную и в двоичную.
- •Задание для самостоятельной работы.
- •Лекция №10. Сложные структуры данных. Массивы. Структуры.
- •4) Mov esi,6*2 ; 2 байта – размер элементов
- •Индексная адресация со смещением — режим адресации, при котором полный адрес формируется из двух компонентов:
- •Базовая индексная адресация со смещением — режим адресации, при котором полный адрес формируется максимум из трех компонентов:
- •Структуры
- •Организовать обращение к элементам структуры.
- •Цепочечные команды или команды обработки строк символов
- •Организация обращения к элементам записи.
- •Iotest record
- •Работа с записями
- •1) Для выделения элемента записи необходимо:
- •2) Чтобы поместить измененный элемент на его место в запись необходимо:
- •3. В конце работы файл следует закрыть.
- •4. Признаком ошибки при выполнении функции dos является взведенный флаг с (переноса).
- •2. Создание файла с усечением существующего до нулевой длины.
- •LpFileName — указатель на asciiz-строку с именем (путем) открываемого или создаваемого файла;
- •DwDesiredAccess — тип доступа к файлу:
- •Лекция №6. Работа с сопроцессором. Команды для работы с fpu. Работа с fpu.
- •Лекция №6. Работа с сопроцессором. Команды для работы с fpu. Работа с fpu.
- •Лекция №6. Работа с сопроцессором. Команды для работы с fpu. Работа с fpu.
- •Лабораторная работа №1. Тема: знакомство с системой программирования Турбо-ассемблер.
- •1) Пересылка данных
- •2) Xor логическое исключающее или
- •3) Команды передачи управления
- •Лабораторная работа №2. Тема: Работа с арифметическими командами.
- •Команды сложения
- •Команды вычитания.
- •Команды умножения.
- •Команда деления
- •Команды преобразования
- •Команды сдвига
- •Лабораторная работа №4. Тема: перевод чисел из шестнадцатиричной системы исчисления в десятичную и в двоичную.
- •Директива extrn Режимы Ideal, masm
- •Преимущества и недостатки ]Преимущества
- •Недостатки
- •Блок-схема вывода на экран вещественного числа, которое хранится в регистре st(0) сопроцессора.
- •Трансцендентные операции fpu
- •Функция MessageBox
- •1) Первой известной кодировкой символов была кодировка ascii, и она используется до сих пор. В ascii-кодировке каждый символ занимает 8 бит, или один байт.
- •2.Адресные операнды – задают физическое расположение операнда в памяти с помощью указания двух составляющих адреса: сегмента и смещения. К примеру:
- •5. Структурные операнды используются для доступа к конкретному элементу структуры.
- •6. Записи (аналогично структурному типу) используются для доступа к битовому полю некоторой записи.
- •4) Нельзя использовать сегментный регистр cs в качестве операнда назначения.
- •5) Оператор ptr можно применять и когда требуется принудительно поменять размерность операндов. К примеру, требуется переслать значение 0ffh во второй байт поля flp:
- •Xchg eax,ebx ; обменять содержимое регистров eax и ebx.
- •Xchg al,al ; а эта команда не делает ничего
- •Xchg ax, word ptr [si] ; обменять содержимое регистра ах и слова в памяти по адресу в [si].
4) Mov esi,6*2 ; 2 байта – размер элементов
Mov ax, Mas[esi] ; ax=01C8
Пусть эта последовательность чисел трактуется как одномерный массив. Размерность каждого элемента определяется директивой dw.
В общем случае для получения адреса элемента в массиве необходимо начальный (базовый) адрес массива сложить с произведением индекса (номер элемента минус единица) этого элемента на размер элемента массива:
база + (индекс*размер элемента)
Способы адресации, используемые при работе с массивами
-
Индексная адресация со смещением — режим адресации, при котором полный адрес формируется из двух компонентов:
-
постоянного (базового) — указанием прямого адреса массива в виде имени идентификатора, обозначающего начало массива (смещения);
-
переменного (индексного) — указанием имени индексного регистра.
К примеру:
mas dw 0,1,2,3,4,5
...
mov si,4
;поместить 3-й элемент массива mas в регистр ax:
mov ax,mas[si]
-
Базовая индексная адресация со смещением — режим адресации, при котором полный адрес формируется максимум из трех компонентов:
-
постоянного (необязательного компонента), в качестве которого может выступать прямой адрес массива в виде имени идентификатора (смещение), или непосредственное значение;
-
переменного (базового) — указанием имени базового регистра;
-
переменного (индексного) — указанием имени индексного регистра.
-
Этот вид адресации используется при обработке двухмерных массивов. Например:
Mov eax,mas[bx][si]
В качестве базового регистра может использоваться любой из восьми регистров общего назначения. В качестве индексного регистра также можно использовать любой регистр общего назначения, за исключением esp/sp.
Микропроцессор позволяет масштабировать индекс. Необходимость в масштабировании возникает при работе с массивами, которые имеют размер элементов, равный 2, 4 или 8 байтам.
Например: Разработать программу, в которой просматривается массив, состоящий из слов, и производится сравнение этих элементов с нулем. Выводится соответствующее сообщение.
Пример 6: Просмотр массива слов с использованием масштабирования
;prg_12_2.asm. Для DOS16.
MASM
MODEL small
STACK 256
.data ;начало сегмента данный
;тексты сообщений:
mes1 db "не равен 0!$",10,13
mes2 db "равен 0!$",10,13
mes3 db 10,13,'Элемент $'
mas dw 2,7,0,0,1,9,3,6,0,8 ;исходный массив
.code
;.486 ;это обязательно
start:
mov ax,@data
mov ds,ax ;связка ds с сегментом данных
xor ax,ax ;обнуление ax
prepare:
mov сx,10 ;значение счетчика цикла в cx
mov esi,0 ;индекс в esi
compare:
mov dx,mas[esi*2] ;первый элемент массива в dx
cmp dx,0 ;сравнение dx с 0
je equal ;переход, если равно
not_equal: ;не равно
mov ah,09h ;вывод сообщения на экран
lea dx,mes3
int 21h
mov ah,02h ;вывод номера элемента массива на экран
mov dx,si
add dl,30h
int 21h
mov ah,09h
lea dx,mes1
int 21h
inc esi ;на следующий элемент
dec сх ;условие для выхода из цикла
jcxz exit ;cx=0? Если да - на выход
jmp compare ;нет - повторить цикл
equal: ;равно 0
mov ah,09h ;вывод сообщения mes3 на экран
lea dx,mes3
int 21h
mov ah,02h
mov dx,si
add dl,30h
int 21h
mov ah,09h ; вывод сообщения mes2 на экран
lea dx,mes2
int 21h
inc esi ;на следующий элемент
dec ex ;все элементы обработаны?
jcxz exit
jmp compare
exit:
mov ax,4c00h ;стандартный выход
int 21h
end main ;конец программы
Возможны следующие случаи при адресации массивов:
-
если для описания адреса используется только один регистр, то такая адресация называется базовой адресацией и этот регистр рассматривается как базовый:
; переслать байт из области данных, адрес которой находится в
; регистре ebx
mov al,[ebx]
2) если для задания адреса в команде используется прямая адресация (в виде идентификатора) в сочетании с одним регистром, то такая адресация называется индексной адресацией. Регистр считается индексным и поэтому можно использовать масштабирование для получения адреса нужного элемента массива:
;сложить содержимое eax с двойным словом в памяти по адресу
; mas + (ebx)*4
add eax,mas[ebx*4]
-
если для описания адреса используются два регистра, то такая адресация называется базово-индексной адресацией. Левый регистр рассматривается как базовый, а правый — как индексный.
Базово-индексную адресацию можно сочетать с прямой адресацией или указанием непосредственного значения. Адрес тогда будет формироваться как сумма всех компонентов.
К примеру:
mov ax,mas[ebx][ecx*2]
;адрес операнда равен [mas+(ebx)+(ecx)*2]
...
sub dx,[ebx+8][ecx*4]
;адрес операнда равен [(ebx)+8+(ecx)*4]
Масштабирование эффективно только, когда размерность элементов массива равна 2, 4 или 8 байтам. Если же размерность элементов другая, то организовывать обращение к элементам массива нужно обычным способом.
Пример 7: Обработка массива элементов с нечетной длиной. Размер элемента массива в три байта. Массив сформировать самостоятельно, следующим образом: первый элемент массива равен Е3 1111h=14 881 041d, все последующие трёхбитные элементы массива равны inc(E3 1111h). В памяти сформировать массив из 16 трёхбитных элемента. Увеличить на единицу в каждом элементе массива значение первого байта. Вывести измененный массив на экран в одну строку. Примечание: Е4 1111h=14 946 577d.
;---------------------------------------------------------------------------
; Версия для Win32 (tri.asm)
.386
.model flat, stdcall
includelib import32.lib
extrn ExitProcess:PROC
extrn MessageBoxA:PROC
.data
Ttl db 'Massiv',0h
mas db 16 dup (3 dup (0)) ; 48 элементов в массиве
; следующую строчку 2 байта 0ah,0dh
mes1 db 'Massiv: ',0ah,0dh
Msg db 150 dup (?)
masVivod db 85 dup (?) ;
var dd 0E31111h
var2 dd ?
var3 dd 00000000h
i db 1
N db 16
tabl db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h
k dd 0
.code
start:
xor ecx,ecx ;обнуление есx
xor edx,edx
mov cl,N ;значение счетчика цикла в cl
mov esi, 0 ;индекс начального элемента в si
;-------------------------------------------------------------------------------------------------
; Заполнение элементов массива значениями var E31111h++
mov eax,var
mov var2,eax
go2:
xor eax,eax
mov al,byte ptr [var+2] ; al=E3h
mov mas[esi],al
inc esi
mov al,byte ptr [var+1] ; al=11h
mov mas[esi],al
inc esi
mov al,byte ptr [var] ; al=11h
mov mas[esi],al
inc esi
inc var
loopnz go2
;--------------------------------------------------------------------------------------------
; Изменение первого байта в каждом элементе массива
mov esi,0 ;0 в si
xor ecx,ecx
mov cl,N
go:
mov dl,mas[esi] ;первый байт поля в dl
inc dl ;увеличение dl на 1 (по условию)
mov mas[esi],dl ;заслать обратно в массив
add esi,3 ;сдвиг на следующий элемент массива
loop go ;повтор цикла
mov cl,N
mov edi,0
mov esi,0
go1:
;----------------------------------------------------------------------------
; Переносим трёхбитное число из массива mas в регистр еах для перевода в
; десятичное число
xor eax,eax
xor ebx,ebx
mov ah,mas[esi]
mov al,mas[esi+1]
mov bl,mas[esi+2]
shl eax,8
add eax,ebx
add esi,3
;-------------------------------------------------------------------------------
; Перевод в десятичную систему исчисления трёхбайтного числа из eax и
; запись десятичного числа в память
push esi
mov ebx,eax
xor eax,eax
xor edx,edx
xor edi,edi
mov dl,i
mov al,8
mul dl
add eax,k
mov edi,eax
xor esi,esi
mov esi,10
push edi
mov eax,ebx
lp2: xor edx,edx
div esi
xchg eax,edx
add al,'0'
mov byte ptr [Msg+edi],al
xchg eax,edx
dec edi
or eax,eax
jne lp2
;-------------------------------------------------------------------------------------
; Ставим символ ";" в качестве разделителя после каждого числа
pop edi
mov byte ptr [Msg+edi+1],';'
inc i
inc k
pop esi
loopnz go1
;---------------------------------------------------------------------------------------
;вывод на экран получившегося массива
push 0h
push offset Ttl
push offset [Msg+1]
push 0h
call MessageBoxA
push 0h
call ExitProcess
end start
Результат:
_______________________________________________________________
Самостоятельно на практике: Создать массив с элементами нечетной длины. Размер элемента массива в три байта. Массив сформировать самостоятельно, следующим образом: первый элемент массива равен Е3 1111h=14 881 041d, все последующие трёхбайтные элементы массива равны inc(E3 1111h). В памяти сформировать массив из 16 трёхбайтных элемента. Увеличить на единицу в каждом элементе массива значение второго байта. Вывести измененный массив на экран построчно так, чтобы в строке было 4 элемента массива.
Двумерные массивы
Обращение к элементам двумерного массива в памяти как к строкам или как к столбцам зависит от алгоритма обработки двумерного массива.
Если последовательность однотипных элементов в памяти трактуется как двумерный массив, расположенный по строкам, то адрес элемента (i, j) вычисляется по формуле:
(база + количество_элементов_в_строке * размер_элемента * i+
+j* размер_элемента)
Здесь i = 0...n-l указывает номер строки, a j = 0...m-l указывает номер столбца.
Например, пусть имеется массив чисел (размером в 1 байт) mas(i,j) с размерностью 4 X 4 (i = 0...3, j = 0...3):
23 04 05 67
05 06 07 99
67 08 09 23
87 09 00 08
В памяти элементы этого массива будут расположены в следующей последовательности:
23 04 05 67 05 06 07 99 67 08 09 23 87 09 00 08
Если необходимо трактовать эту последовательность как двумерный массив и извлечь, например, элемент mas(2, 3) = 23, то, убедимся что:
Полный адрес mas(2, 3) = mas + 4 * 1 * 2 + 3*1 = mas + 11
Организовывают адресацию двумерного массива, используя базово-индексную адресацию. При этом возможны два основных варианта выбора компонентов для формирования полного адреса:
-
сочетание прямого адреса, как базового компонента адреса, и двух индексных регистров для хранения индексов:
mov ax,mas[ebx][esi]
-
сочетание двух индексных регистров, один из которых является и базовым, и индексным одновременно, а другой — только индексным:
mov ax,[edi][esi]
Пример 1: Фрагмент программы выборки элемента массива mas(2,3) и запись его значения в регистр al.
.data
mas db 23,4,5,67,5,6,1,99,67,8,9,23,87,9,0,8
i=2
j=3
; 23 04 05 67
; 05 06 01 99
; 67 08 09 23
; 87 09 00 08
.code
...
mov si,4*1*i ; 1 – размер элемента массива 1 байт
mov di,j*1 ; 1 - размер элемента массива 1 байт
mov al,mas[si][di] ;в аl элемент mas(2,3)=23
Пример 2: Фрагмент программы выборки элемента массива mas(2,3) и его обнуления
.data
mas dw 23,4,5,67,5,6,1,99,67,8,9,23,87,9,0,8
i=2
j=3
; 00 23 00 04 00 05 00 67
; 00 05 00 06 00 01 00 99
; 00 67 00 08 00 09 00 23
; 00 87 00 09 00 00 00 08
.code
...
mov si,4*2*i ; =16; 2 – размер элемента массива 2 байта
mov di,j*2 ; =6
mov ах,mas[si][di] ; в аx элемент mas(2,3)=mas+16+6=mas+22
; ax=0023
Типовые операции с массивами
Пример 8. Поиск элемента в двумерном массиве. Элементы массива размером в слово. Размер массива 2х5. Искомый элемент 333. (find.asm)
.386
.model flat, stdcall
includelib import32.lib
extrn ExitProcess:PROC
extrn MessageBoxA:PROC
.data
Ttl db 'Find in massiv: ',0h
Msg db 150 dup (?)
;матрица размером 2х5 - если ее не инициализировать,
;то для наглядности она может быть описана так:
;array dw 2 DUP (5 DUP (?))
;но мы ее инициализируем:
array dw 333,333,333,45,55,333,333,2,333,333
;логически это будет выглядеть так:
;аггау= {333 333} 01 4D 01 4D
; {333 45} 01 4D 00 2D
; {55 333} 00 37 01 4D
; {333 2} 01 4D 00 02
; {333 333} 01 4D 01 4D
elem dw 333 ;элемент для поиска 01 4D
failed db 0ah,0dh,'Net takogo elementa v massive!',0h
success db 0ah,0dh,'Takou element prisytstvyet v massive '
foundtime db ? ;количество найденных элементов
fnd db " raz(a)",0ah,0dh,0h
.code
start:
xor ax,ax
mov esi,0 ;esi=столбцы в матрице
mov ebx,0 ;ebx=строки в матрице
mov ecx,5 ;число для внешнего цикла (по строкам)
external: ; внешний цикл по строкам
push ecx ; сохранение в стеке значение
; счетчика внешнего цикла
mov ecx,2 ;число для внутреннего цикла (по столбцам)
mov esi,0
iternal: ;внутренний цикл по столбцам
mov ax,array[ebx][esi] ;сравниваем содержимое текущего элемента в
; ax с искомым элементом:
inc esi ;передвижение на следующий элемент в строке
inc esi
cmp ax,elem ;если текущий совпал с искомым, то переход на
; here для обработки, иначе - цикл продолжения
; поиска
je here
;иначе - цикл по строке cx=2 раз
loop iternal
jmp move_next
here:
inc foundtime ;иначе - увеличиваем счетчик совпавших
sub ecx,1
cmp esi,4 ;просмотрели строку?
je move_next
jmp iternal
move_next: ;продвижение в матрице
pop ecx ;восстанавливаем CX из стека (5)
add ebx,4 ;передвигаемся на следующую строку
loop external ;цикл (внешний)
;______________________________________________________Конец поиска
cmp foundtime,0h ;сравнение числа совпавших с 0
ja eql ;если больше 0, то переход
not_equal: ;нет элементов, совпавших с искомым
push 0h
push offset Ttl
push offset failed
push 0h
call MessageBoxA
jmp exit ;на выход
eql: ;есть элементы, совпавшие с искомым
xor eax,eax
mov al,foundtime
add al,30h
mov foundtime,al
push 0h
push offset Ttl
push offset success
push 0h
call MessageBoxA
exit:
push 0h
call ExitProcess
end start
При анализе работы программы принято, что элементы массива нумеруются с 0. При поиске определенного элемента массив просматривается от начала и до конца. Программа сохраняет в поле foundtime количество вхождений искомого элемента в массив. В качестве индексных регистров используются si и bx.
_____________________________________________________________
Самостоятельно на практике: Разработать программу для работы с двумерным массивом размерностью 3х5. В массиве определить количество элементов, которые больше среднего арифметического всех элементов массива. Элементы массива размером в слово. Для подсчёта среднего арифметического можно использовать сопроцессор.