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

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

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

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

. . .

T db ′Текст для вывода на экран$’

. . .

data ends

то для вывода этого текста на экран можно выполнить следующий фрагмент программы

. . .

mov DX,offset T; DX:=адрес T

outstr

. . .

Рассмотрим теперь пример простой полной программы на Ассемблере. Эта программа должна вводить значение целой переменной A и реализовывать оператор присваивания (в смысле языка Паскаль)

X := (2*A - 241 div (A+B)2) mod 7

где B – параметр, т.е. значение, которое не вводится, а задаваётся в самой программе. Пусть A, B и С – знаковые целые величины, описанные в сегменте данных так:

A dw ?

B db –8; это параметр, заданный программистом

X dw ?

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

Наша программа будет содержать три сегмента с именами data, code и stack и выглядеть следующим образом:

include io.asm

; вставить в программу файл с макроопределениями

; для макрокоманд ввода-вывода

data segment

A dw ?

B db -8

X dw ?

Data ends

stack segment stack

db 128 dup (?)

stack ends

code segment

assume cs:code, ds:data, ss:stack

start:mov ax,data; это команда формата r16,i16

mov ds,ax ; загрузка сегментного регистра DS

inint A ; макрокоманда ввода целого числа

mov bx,A ; bx := A

mov al,B ; al := B

cbw ; ax := длинное B

add ax,bx ; ax := B+A=A+B

add bx,bx ; bx := 2*A

imul ax ; (dx,ax) := (A+B)2

mov cx,ax ; cx := младшая часть(A+B)2

mov ax,241

cwd ; <dx,ax> := сверхдлинное 241

idiv cx ; ax := 241 div (A+B)2 , dx := 241 mod (A+B)2

sub bx,ax ; bx := 2*A - 241 div (A+B)2

mov ax,bx

cwd

mov bx,7

idiv bx ; dx := (2*A - 241 div (A+B)2) mod 7

mov X,dx

outint X

finish

code ends

end start

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

В начале сегмента кода расположена директива assume, она говорит программе Ассемблера, на какие сегменты будут указывать соответствующие сегментные регистры при выполнении команд, обращающихся к этим сегментам. Сама эта директива не меняет значения ни одного сегментного регистра, подробно про неё необходимо прочитать в учебнике [5].

Заметим, что сегментные регистры SS и CS должны быть загружены перед выполнением самой первой команды нашей программы. Ясно, что сама наша программа этого сделать не в состоянии, так как для этого необходимо выполнить хотя бы одну команду, что требует доступа к сегменту кода, и, в свою очередь, уже установленного на этот сегмент регистра CS. Получается замкнутый круг, и единственным решением будет попросить какую-то другую программу загрузить значения этих регистров, перед вызовом нашей программы. Как мы потом увидим, эту операцию будет делать служебная программа, которая называется загрузчиком.

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

mov ds,data; формат SR,i16 такого формата нет!

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

mov ax,data

будет во время счёта иметь вид

mov ax,6250 ; 100000 div 16 = 6250

Макрокоманда

inint A; макрокоманда ввода целого числа

вводит значение целого числа в переменную A.

Далее начнём непосредственное вычисление правой части оператора присваивания. Задача усложняется тем, что величины A и B имеют разную длину и непосредственно складывать их нельзя. Приходится командами

mov al,B ; al := B

cbw ; ax := длинное B

преобразовать короткое целое B, которое сейчас находится на регистре al, в длинное целое на регистре ax. Далее вычисляется значение выражения (A+B)2 и можно приступать к выполнению деления. Так как делитель является длинным целым числом (мы поместили его на регистр cx), то необходимо применить операцию длинного деления, для чего делимое (число 241 на регистре ax) командой

cwd

преобразуем в сверхдлинное целое и помещаем на два регистра (dx,ax). Вот теперь всё готово для команды целочисленного деления

idiv cx; ax:= 241 div (A+B)2 , dx:= 241 mod (A+B)2

Далее мы присваиваем остаток от деления (он в регистре dx) переменной X и выводим значение этой переменной по макрокоманде

outint X

которая эквивалентна процедуре WriteLn(X) языка Паскаль. Последним предложением в сегменте кода является макрокоманда

finish

Эта макрокоманда заканчивает выполнение нашей программы, она эквивалентна выходу программы на Паскале на конечный end.

И, наконец, директива

end start

заканчивает описание всего модуля на Ассемблере. Обратите внимание на параметр этой директивы – метку start. Она указывает входную точку программы, т.е. её первую выполняемую команду программы.

Сделаем теперь важные замечания к нашей программе. Во-первых, мы не проверяли, что команды сложения и вычитания дают правильный результат (для этого, как мы знаем, после выполнения этих команд нам было бы необходимо проверить флаг переполнения OF, т.к. наши числа мы считаем знаковыми). Во-вторых, команда длинного умножения располагает свой результат в двух регистрах (dx,ax), а в нашей программе мы брали результат произведения только из регистра ax, предполагая, что на регистре dx находятся только незначащие цифры произведения. По-хорошему надо было бы проверить, что в dx содержаться только нулевые биты, если ax  0, и только двоичные “1”, если

ax < 0. Другими словами, знак числа в регистре dx должен совпадать со знаком числа в регистре ax, для знаковых чисел это и есть признак того, что в регистре dx содержится незначащая часть произведения. И, наконец, мы не проверили, что не производим деления на ноль (в нашем случае что A<>8). В наших учебных программах мы иногда не будем делать таких проверок, но в “настоящих” программах, которые Вы будете создавать на компьютерах и предъявлять преподавателям, эти проверки являются обязательными.

Продолжая знакомство с языком Ассемблера, решим следующую задачу. Напишем фрагмент программы, в котором увеличивается на единицу целое число, расположенное в 23456710 байте оперативной памяти. Мы уже знаем, что запись в любой байт памяти возможна только тогда, когда этот байт расположен в одном из четырёх текущих сегментах. Сделаем, например, так, чтобы наш байт располагался в сегменте данных. Главное здесь – не путать сегменты данных, которые мы описываем в программе на Ассемблере, с активными сегментами, на начала которых установлены сегментные регистры. Описываемые в программе сегменты обычно размещаются загрузчиком на свободных участках оперативной памяти, и, как правило, при написании текста программы неизвестно их будущего месторасположение.14 Однако ничто не мешает нам любой участок оперативной памяти сделать сегментом, установив на него какой-либо сегментный регистр. Так мы и сделаем для решения нашей задачи, установив сегментный регистр DS на начало ближайшего сегмента, в котором будет находиться наш байт с адресом 23456710. Так как в сегментный регистр загружается адрес начала сегмента, делённый на 16, то нужное нам значение сегментного регистра можно вычислить по формуле: DS := 234567 div 16 = 14660. При этом адрес A нашего байта в сегменте (его смещение от начала сегмента) вычисляется по формуле: A := 234567 mod 16 = 7. Таким образом, для решения нашей задачи можно предложить следующий фрагмент программы:

mov ax,14660

mov ds,ax; Начало сегмента

mov bx,7; Смещение

inc byte ptr [bx]

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

7.5. Переходы

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

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

  • Переходы, вызванные выполнением центральным процессором специальных команд переходов.

  • Переходы, которые автоматически выполняет центральный процессор при наступлении определённых событий в центральной части компьютера или в его периферийных устройствах (устройствах ввода/вывода).

Начнём последовательное рассмотрение переходов для компьютеров нашей архитектуры. Напомним, что физический адрес начала следующей выполняемой команды зависит от значений двух регистров: сегментного регистра CS и счётчика адреса IP и вычисляется по формуле:

Aфиз := (CS*16 + IP)mod 220

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

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

IP := (IP + Const)mod 216

При абсолютном переходе происходит просто присваивание соответствующему регистру нового значения, например,

CS := Const

Опять же из соображений ценности практического использования в программировании, для сегментного регистра CS реализован только абсолютный переход, в то время как для счётчика адреса IP возможен как абсолютный, так и относительный переходы.

Далее будем классифицировать относительные переходы по величине той константы, которая прибавляется к значению счётчика адреса IP: при коротком переходе величина этой знаковой константы (напомним, что мы обозначаем её i8) не превышает по размеру одного байта (т.е. лежит в диапазоне от –128 до +127):

IP := (IP + i8)mod 216 ,

а при длинном переходе эта константа имеет размер слова (двух байт):

IP := (IP + i16)mod 216

Кроме того, величина, используемая при абсолютном переходе для задания нового значения какого-либо из этих регистров, может быть прямой и косвенной. Прямая величина является просто числом (в нашей терминологии это непосредственный адрес), а косвенная – является адресом некоторой области памяти, откуда и будет извлекаться необходимое число, например,

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

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

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

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