Главная » Просмотр файлов » В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования

В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования (975817), страница 14

Файл №975817 В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования (В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования.doc) 14 страницаВ.Г. Баула - Введение в архитектуру ЭВМ и системы программирования (975817) страница 142019-04-28СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 14)

mov bx,offset X; указатель на X[1]

mov si,offset Y+2*N-2; указатель на Y[N]

L3: mov ax,[bx]; первый сомножитель

mul word ptr es:[si]; умножение на Y[N-i+1]

jc Err; большое произведение

add S,ax

jc Err; большая сумма

add bx,type X; это bx:=bx+2

sub si,2; это i:=i-1

loop L3; цикл суммирования

mov dx, offset T2

outstr

outword S

newline

finish

Err: mov dx,T3

outstr

finish

code ends

end begin_of_program

Подробно прокомментируем эту программа. Количество элементов массивов мы задали, используя директиву эквивалентности N equ 20000 , это есть указание программе Ассемблера о том, что всюду в программе, где встретится имя N, надо подставить вместо него операнд этой директивы – число 20000. Таким образом, это почти полный аналог описания константы в языке Паскаль.20 Под каждый из массивов директива dw зарезервирует 2*N байт памяти.

Заметим теперь, что оба массива не поместятся в один сегмент данных (в сегменте не более примерно 32000 слов, а у нас в сумме 40000 слов), поэтому массив X мы размещаем в сегменте data1, а массив Y – в сегменте data2. Директива assume говорит, что на начала этих сегментов будут соответственно указывать регистры ds и es, что мы и обеспечили в самом начале программы. При вводе массивов мы использовали индексный регистр bx, в котором находится смещение текущего элемента массива от начала этого массива.

При вводе массива Y мы для учебных целей вместо предложения

L2: inint Y[bx];ввод очередного элемента

записали два предложения

L2: inint ax

mov Y[bx],ax;ввод очередного элемента

Это мы сделали, чтобы подчеркнуть: при доступе к элементам массива Y Ассемблер учитывает то, что имя Y описано в сегменте data2 и автоматически (используя информацию из директивы assume) поставит перед командой mov Y[bx],ax специальную однобайтную команду es: . Эту команду называют префиксом программного сегмента, так что на языке машины у нас будут две последовательные, тесно связанные команды:

es: mov Y[bx],ax

В цикле суммирования произведений для доступа к элементам массивов мы использовали другой приём, чем при вводе – регистры-указатели bx и si, в этих регистрах находятся адреса очередных элементов массивов. Напомним, что адрес – это смещение элемента относительно начала сегмента (в отличие от индекса элемента – это смещение от начала массива).

При записи команды умножение

mul word ptr es:[si]; умножение на Y[N-i+1]

мы вынуждены явно задать размер второго сомножителя и записать префикс программного сегмента es:, так как по виду операнда [si] Ассемблер не может сам "догадаться", что это элемент массива Y размером в слово и из сегмента data2.

В команде

add bx,type X; это bx:=bx+2

для задания размера элемента массива мы использовали оператор type. Параметром этого оператора является имя из нашей программы, значением оператора type <имя> является целое число – тип данного имени. Для имён областей памяти это длина этой области в байтах (для массива это почти всегда длина одного элемента), для меток команд это отрицательное число –1, если метка расположена в том же сегменте, что и оператор type, или отрицательное число –2 для меток из других сегментов. Все остальные имена имеют тип ноль.

Вы, наверное, уже почувствовали, что программирование на Ассемблере сильно отличается от программирования на языке высокого уровня (например, на Паскале). Чтобы подчеркнуть это различие, рассмотрим пример задачи, связанной с обработкой матрицы, и решим её на Паскале и на Ассемблере.

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

Const N=20; M=30;

Var X: array[1..N,1..M] of integer;

Sum,i,j: integer;

. . .

{ Ввод матрицы X }

Sum:=0;

for i:=1 to N do

if X[i,1]<0 then

for j:=1 to M do Sum:=Sum+X[i,j];

Сначала обратим внимание на то, что переменные i и j несут в программе на Паскале двойную нагрузку: это одновременно и счётчики циклов, и индексы элементов массива. Такое совмещение функций упрощает понимание программы и делает её очень компактной по внешнему виду, но не проходит даром: чтобы по индексам элемента массива вычислить его адрес в сегменте, приходится выполнить достаточно сложные действия. Например, адрес элемента X[i,j] приходится вычислять так:

Адрес(X[i,j])= Адрес(X[1,1])+2*M*(i-1)+2*(j-1)

Эту формулу легко понять, учитывая, что матрица хранится в памяти по строкам (сначала первая строка, затем вторая и т.д.), и каждая строка имеет длину 2*M байт. Буквальное вычисление адресом элементов по приведённой выше формуле (а именно так чаще всего и делает Паскаль-машина) приводит к весьма неэффективной программе. При программировании на Ассемблере лучше всего разделить функции счётчика цикла и индекса элементов. В качестве счётчика лучше всего использовать регистр cx (он и специализирован для этой цели), а адреса лучше хранить в индексных регистрах (bx, si и di). Исходя из этих соображений, можно так переписать программу на Паскале, предвидя её будущий перенос на Ассемблер.

Const N=20; M=30;

Var X: array[1..N,1..M] of integer;

Sum,cx,oldcx: integer; bx: ↑integer;

. . .

{ Ввод матрицы X }

Sum:=0; bx:=↑X[1,1]; {Так в Паскале нельзя}

for cx:=N downto 1 do

if bx↑<0 then begin oldcx:=cx;

for cx:=M downto 1 do begin

Sum:=Sum+bx↑; bx:=bx+2 {Так в Паскале нельзя}

end;

cx:=oldcx

end

else bx:=bx+2*M {Так в Паскале нельзя}

Теперь осталось переписать этот фрагмент программы на Ассемблере:

N equ 20

M equ 30

oldcx equ di

Data segment

X dw N*M dup (?)

Sum dw ?

. . .

Data ends

. . .

; Ввод матрицы X

mov Sum,0

mov bx,offset X; Адрес X[1,1]

mov cx,N

L1: cmp word ptr [bx],0

jge L3

mov oldcx,cx

mov cx,M

L2: mov ax,[bx]

add Sum,ax

add bx,2

loop L2

mov cx,oldcx

jmp L4

L3: add bx,2*M

L4: loop L1

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

Вернёмся к описанию команд цикла. В языке Ассемблера есть и другие команды цикла, которые могут производить досрочный (до исчерпания счётчика цикла) выход из цикла. Как и для команд условного перехода, для мнемонических имен некоторых из них существуют синонимы, которые мы будем разделять в описании этих команд символом /.

Команда

loopz/loope L

выполняется по схеме

Dec(CX); if (CX<>0) and (ZF=1) then goto L;

А команда

loopnz/loopne L

выполняется по схеме

Dec(CX); if (CX<>0) and (ZF=0) then goto L;

В этих командах необходимо учитывать, что операция Dec(CX) является частью команды цикла и не меняет флага ZF.

Как видим, досрочный выход из таких циклов может произойти при соответствующих значениях флага нуля ZF. Такие команды используются в основном при работе с массивами, для усвоения этого материала Вам необходимо изучить соответствующий раздел учебника по Ассемблеру.

7.7. Работа со стеком

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

Стеком называется сегмент памяти, на начало которого указывает сегментный регистр SS. При работе программы в регистр SS можно последовательно загружать адреса начал нескольких сегментов, поэтому иногда говорят, что в программе несколько стеков. Однако в каждый момент стек только один – тот, на который сейчас указывает регистр SS. Именно этот стек мы и будем иметь в виду.

Кроме начала, у стека есть текущая позиция – вершина стека, её смещение от начала сегмента стека записано в регистре SP (stack pointer). Следовательно, как мы уже знаем, физический адрес вершины стека можно получить по формуле Афиз = (SS*16 + SP)mod 220.

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

В соответствие с определением понятия стек последнее записанное в него слово будет читаться из стека первым. Это так называемое правило "последний пришёл – первый вышел" (английское сокращение LIFO).21 Обычно стек принято изображать "растущим" снизу-вверх. Как следствие получается, что конец стека фиксирован и расположен снизу, а вершина двигается вверх (при записи в стек) и вниз (при чтении из стека).

В каждый момент времени регистр SP указывает на последнее слово, записанное в стек. Обычно стек изображают, как показано на рис. 7.1.

Начало стека SS 

Вершина стека SP 

Конец стека 

SP для пустого стека 

Рис. 7.1. Так мы будем изображать стек.

На нашем рисунке, как обычно, стек растёт снизу-вверх, занятая часть стека закрашена. В начале работы программы, когда стек пустой, регистр SP указывает на первое слово за концом стека. Особым является случай, когда стек имеет максимальный размер 216 байт, в этом случае значение регистра SP для пустого стека равно нулю, т.е. совпадает со значением этого регистра и для полного стека, поэтому стеки максимального размера использовать не рекомендуется, так как будет затруднён контроль пустоты и переполнения стека.

Обычно для резервирования памяти под стек на языке Ассемблера описывается специальный сегмент стека. В наших предыдущих программах мы делали это таким образом:

stack segment stack

dw 64 dup (?)

stack ends

Имя сегмента стека и способ резервирования памяти может быть любым, например, можно описать такой стек:

st_1 segment stack

db 128 dup (?)

st_1 ends

То, что этот сегмент будет при выполнении программы использоваться именно как сегмент стека, указывается параметром stack директивы segment. Этот параметр является служебным словом языка Ассемблера и, вообще говоря, не должен употребляться ни в каком другом смысле. 22

В нашем последнем примере размер сегмента стека установлен в 64 слова, поэтому в начале работы регистр SP будет иметь значение 128, т.е., как мы и говорили ранее, указывает на первое слово за концом стека. Области памяти в стеке обычно не имеют имён, так как доступ к ним, как правило, производится только с использованием регистров.

Обратим здесь внимание на важное обстоятельство. Перед началом работы со стеком необходимо загрузить в регистры SS и SP требуемые значения, однако сама программа это сделать не может, т.к. при выполнении самой первой команды программы стек уже должен быть доступен (почему это так мы узнаем в нашем курсе позже, когда будем изучать механизм прерываний). Поэтому в рассмотренных выше примерах программ мы сами не загружали в регистры SS и SP никаких начальных значений. Как мы узнаем позже, перед началом выполнения нашей программы этим регистрам присвоит значения специальная системная программа загрузчик, которая размещает нашу программу в памяти и передаёт управление на команду, помеченную той меткой, которая указана в конце нашего модуля в качестве параметра директивы end. Разумеется, позже при работе программы мы и сами можем загрузить в регистр SS новое значение, это будет переключением на другой сегмент стека.

Рассмотрим сначала те команды работы со стеком, которые не являются командами перехода. Команда

push op1

где op1 может иметь форматы r16, m16, CS,DS,SS,ES, записывает в стек слово, определяемое своим операндом. Это команда выполняется по правилу:

SP := (SP – 2)mod 216 ; <SS,SP> := op1

Здесь запись <SS,SP> обозначает адрес в стеке, вычисляемый по формуле

Характеристики

Тип файла
Документ
Размер
1,7 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6381
Авторов
на СтудИзбе
308
Средний доход
с одного платного файла
Обучение Подробнее