- •Аппаратно-ориентированное программирование
- •Ббк 32.973.73
- •Удк 681.3 ббк 32.973.73ф 73
- •1. Основы программирования на ассемблере
- •1.1. Принципы построения ассемблерных программ
- •1.2. Понятие архитектуры компьютера
- •1.3. Регистры программиста в ia32
- •1.4. Описание сегментной структуры программы
- •2. Простейшие средства ассемблера
- •2.1. Средства описания данных
- •2.2. Обращения к функциям ос посредством прерываний
- •2.3. Средства преобразования в исполняемый файл
- •2.4. Управление строками при выводе и ввод данных
- •2.5. Простейшие способы адресации
- •3. Архитектурные элементы для построения программ
- •3.1. Организация условных переходов
- •3.2. Средства организации циклов
- •3.3. Особенности команд умножения и деления
- •3.4. Организация процедур
- •3.5. Неарифметические операции над кодами
- •4. Использование неэлементарных способов адресации
- •4.1. Косвенно-регистровая адресация
- •4.2. Использование индексной адресации данных
- •4.3. Базовая и индексно базовая адресации
- •4.4. Адресация с масштабированием
- •5. Взаимосвязи программных единиц
- •5.1. Многомодульная разработка программ
- •5.2. Использование библиотек объектных модулей
- •5.3. Организация стекового кадра подпрограммы
- •5.4. Программный доступ к системным функциям Win32
- •5.5. Особенности использования объектных файлов формата coff
- •5.6. Стандартный доступ к системным функциям Unix
- •6. Вспомогательные средства базовой архитектуры
- •6.1. Использование строковых команд пересылки
- •6.2. Применение строковых команд сравнения
- •7. Использование ассемблерных отладчиков
- •7.1. Особенности отладчика gdb для программ в Linux
- •7.2. Отладчики текстового режима для Windows
- •Библиографический список
- •Оглавление
4.4. Адресация с масштабированием
Как уже пояснялось при обсуждении индексного способа адресации, этот способ требует изменения значения индексного регистра не на величину изменения индекса (увеличения или уменьшения этого значения на единицу в наиболее употребительных ситуациях), а на величину, равную произведению изменения индекса на размер элемента массива.
В более поздних разработках оказалось возможным возложить переход от значения индекса к значению вычисляемых значений на аппаратуру в ходе выполнения команды, а именно в ходе интерпретации операнда с уточнениями по способу адресации. В результате возник еще один способ адресации, являющийся по существу лишь модификацией индексного способа адресации. Он получил название способа адресации с масштабированием.
В этом способе в операнде записывается обозначение индексного регистра, а вместе с ним и значение одной из стандартных длин элементов массива. В качестве таких стандартных длин допустимы только 2, 4 или 8. Операнд, записанный в этом способе адресации имеет вид
[имя_области+масштаб*индексный_регистр] или
[базовый_регистр+смещение+масштаб*индексный_регистр],
где параметр масштаба должен задаваться только числом 2, 4 или 8.
Далее в листинге 4.4.1 приведен пример использования способа адресации с масштабированием. Этот пример выполняет поиск максимального в массиве чисел.
GLOBAL _start
SEGMENT .text
_start:
mov esi, 0 ; esi=index = 0
mov eax, [narray+4*esi] ; или просто [narray]; eax - текущее значение max
met1: cmp eax, [narray+4*esi] ; сравнение max и narray[index]
jg next
mov eax, [narray+4*esi] ; поместить narray[index] в eax
next: inc esi
cmp esi, 10 ; проверены ли все 10 элементов массива?
jl met1
; полученный max в eax
mov esi,10 ; base of position digit system
mov ecx, 0 ; reset digit counter
pov: mov edx, 0 ; null into left part of devident
div esi ; divide for next digit = rest
add dl, '0'
push edx
inc ecx ; step into counter
cmp eax, 0
jne pov
mov [cnt], ecx
mov ebx, formax
izv: pop edx
mov byte [ebx],dl ; digit into array for text value
inc ebx
loop izv ; izv,ecx
;--- write(1, txtmes, lenmes+[cnt]) == <4>(ebx, ecx, edx)
mov eax,4 ; N function=write
mov ebx,1 ; N handle=1 (stdout)
mov edx,[cnt] ; number of byte
add edx, lenmes
mov ecx, txtmes ; address of txtmes (и далее formax)
int 80h
mov eax,1
int 80h ; function=exit for Linux
SEGMENT .data
narray dd 3,17,-5,27,0,-11,17,33,-1,9
txtmes db 'Максимальное число в массиве есть '
lenmes equ $-txtmes
cnt dd 0
SEGMENT .bss
formax resb 10
Листинг 4.4.1. Поиск максимума в массиве чисел
на основе адресации с масштабированием
В этой программе для доступа к i-му элементу массива narray используется задание операнда в виде [narray+4*esi], где индексный регистр esi содержит значение этого индекса, а стоящее перед ним обозначение 4* задает масштаб - размер элемента используемого массива. (В данном примере массив состоит из четырехбайтовых слов, поэтому применен масштаб 4). Согласованно с использованием масштабирования значение индексного регистра изменяется в данном примере на единицу командой инкрементирования, а определение завершения цикла организуется на основе сравнения значения в регистре esi с первым значением индекса за пределами массива (числом 10). Читателю для сравнения следует обратиться к ранее рассмотренному примеру решения той же задачи в листинге 4.2.1, где был использован обычный индексный способ адресации. (Там приходилось сравнивать со значением 10*4 и увеличивать индексный регистр на 4.)
Способ адресации с масштабированием позволяет не только более явно задавать действия с элементами числовых массивов, но и сократить число ошибок, возникающих от расхождения математического понятия индекса со значением индексного регистра в простых способах адресации.