Основни компоненти на асемблерния език и командна структура. Общи характеристики на системата за езикови инструкции на Асемблер за IBM-PC (базов набор от инструкции, методи за адресиране на главния операнд)

Основни компоненти на асемблерния език и командна структура.  Общи характеристики на системата за езикови инструкции на Асемблер за IBM-PC (базов набор от инструкции, методи за адресиране на главния операнд)
Основни компоненти на асемблерния език и командна структура. Общи характеристики на системата за езикови инструкции на Асемблер за IBM-PC (базов набор от инструкции, методи за адресиране на главния операнд)

Тема 2.5 Основи на програмирането на процесора

С увеличаването на продължителността на програмата става по-трудно да се запомнят кодовете за различни операции. Мнемониката предоставя известна помощ в това отношение.

Езикът за кодиране на символни инструкции се нарича асемблер.

асемблерен езике език, в който всеки оператор отговаря на точно една машинна инструкция.

Сглобяваненаречено конвертиране на програма от асемблер, т.е. подготвяне на програма на машинен език чрез заместване на символни имена на операции с машинни кодове и символни адреси с абсолютни или относителни числа, както и включване на библиотечни програми и генериране на последователности от символни инструкции чрез указване на специфични параметри в микроинструкции. Тази програмаобикновено се поставя в ROM или се въвежда в RAM от някакъв външен носител.

Асемблерният език има няколко характеристики, които го отличават от езиците на високо ниво:

1. Това е едно към едно съответствие между операторите на асемблерния език и машинните инструкции.

2. Програмистът на асемблерния език има достъп до всички обекти и команди, налични на целевата машина.

Разбирането на основите на програмирането на машинно-ориентирани езици е полезно за:



По-добро разбиране на компютърната архитектура и по-добро използване на компютрите;

Да се ​​разработят по-рационални структури на алгоритми за програми за решаване на приложни задачи;

Възможността за преглеждане и коригиране на изпълними програми с разширение .exe и .com, компилирани от всякакви езици на високо ниво, в случай на загуба на изходните програми (чрез извикване на тези програми в програмата за отстраняване на грешки в програмата DEBUG и декомпилиране на показването им на асемблер );

Компилация на програми за решаване на най-критичните задачи (програма, компилирана на машинно-ориентиран език, обикновено е по-ефективна - по-кратка и по-бърза с 30-60 процента от програмите, получени в резултат на превод от езици на високо ниво)

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

Програма на асемблерен език може да работи само на компютри от едно и също семейство, докато програма, написана на език от високо ниво, може потенциално да работи на различни машини.

Азбуката на асемблерния език се състои от ASCII знаци.

Числата са само цели числа. Разграничаване:

двоични числа, завършват с буквата B;

Десетични числа, завършващи с D;

Шестнадесетични числа, завършваща с буквата N.

RAM, регистри, представяне на данни

За определена серия от MP се използва индивидуален език за програмиране - асемблер.

Асемблерният език заема междинна позиция между машинните кодове и езиците от високо ниво. Програмирането на този език е по-лесно. Програмата на асемблерния език използва възможностите на определена машина (по-точно MP) по-рационално от програма на език от високо ниво (което е по-лесно за програмист, отколкото за асемблер). Ще разгледаме основните принципи на програмиране на машинно-ориентирани езици, използвайки като пример асемблерния език за MP KR580VM80. За програмиране на езика се използва обща техника. Специфичните техники за запис на програми са свързани с архитектурата и характеристиките на командната система на целевия MP.

Софтуерен модел микропроцесорна системана базата на MP KR580VM80

Програмният модел на MPS в съответствие с фигура 1

MP портове памет

С З AC П ° С

Снимка 1

От гледна точка на програмиста, KR580VM80 MP има следните програмно достъпни регистри.

А– 8-битов акумулаторен регистър. Това е основният регистър на МП. Всяка операция, извършена в ALU, включва поставяне на един от операндите за обработка в акумулатора. Резултатът от операцията в ALU също обикновено се съхранява в A.

B, C, D, E, H, L– 8-битови регистри с общо предназначение (RON). Вътрешна памет MP. Предназначен да съхранява обработената информация, както и резултатите от операцията. При обработката на 16-битови думи от регистрите се образуват двойки BC, DE, HL, като дуалният регистър се нарича първа буква - B, D, H. В регистровата двойка първият регистър е най-високият. Регистрите H, L, използвани както за съхраняване на данни, така и за съхраняване на 16-битови адреси на RAM клетки, имат специално свойство.

ЕТ– флагов регистър (feature register) 8-битов регистър, който съхранява пет характеристики на резултата от извършване на аритметични и логически операции в MP. FL формат според снимката

Бит C (CY - пренасяне) - пренасяне, зададено на 1, ако е имало пренасяне от горния ред на байта при извършване на аритметични операции.

Bit P (паритет) - паритет, се задава на 1, ако броят на единиците в битовете на резултата е четен.

AC битът е допълнителен пренос, предназначен да съхранява пренасящата стойност от долната тетрада на резултата.

Бит Z (нула) - задава се на 1, ако резултатът от операцията е 0.

Битът S (знак) е настроен на 1, ако резултатът е отрицателен, и на 0, ако резултатът е положителен.

SP-- указателят на стека, 16-битов регистър, е проектиран да съхранява адреса на мястото в паметта, където е записан последният байт, въведен в стека.

RS– програмен брояч (програмен брояч), 16-битов регистър, предназначен да съхранява адреса на следващата изпълнима инструкция. Съдържанието на програмния брояч автоматично се увеличава с 1 веднага след извличането на следващия байт с инструкции.

В началната област на паметта на адрес 0000H - 07FF има контролна програма и демонстрационни програми. Това е ROM зоната.

0800 - 0AFF - адресна област за запис на програмите, които се изучават. (RAM).

0В00 - 0ВВ0 - адресна област за запис на данни. (RAM).

0BB0 е началният адрес на стека. (RAM).

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

Формат на данни на асемблерния език и структура на командите

Паметта MP KR580VM80 е масив от 8-битови думи, наречени байтове.Всеки байт има свой собствен 16-битов адрес, който определя неговата позиция в последователността от клетки на паметта. MP може да адресира 65536 байта памет, която може да съдържа както ROM, така и RAM.

Формат на данните

Данните се съхраняват в паметта като 8-битови думи:

D7 D6 D5 D4 D3 D2 D1 D0

Най-малко значимият бит е бит 0, най-значимият бит е бит 7.

Командата се характеризира с формата, т.е. броят битове, заделени за нея, които се разделят байт по байт в определени функционални полета.

Формат на командата

Командите MP KR580VM80 имат един, два или три байта формат. Многобайтовите инструкции трябва да бъдат поставени в съседни PL. Форматът на командата зависи от спецификата на извършваната операция.

Първият байт на командата съдържа операционния код, написан в мнемонична форма.

Той определя формата на командата и действията, които трябва да бъдат извършени от MP върху данните по време на нейното изпълнение, и начина на адресиране, като може да съдържа и информация за местоположението на данните.

Вторият и третият байт могат да съдържат данни, с които да се работи, или адреси, които показват местоположението на данните. Данните, върху които се извършват операции, се наричат ​​операнди.

Еднобайтов команден формат съгласно фигура 2

Фигура 4

В инструкциите на асемблерния език операционният код има съкратена форма на писане на английски думи - мнемонична нотация. Мнемониката (от гръцки mnemonic - изкуството на запаметяването) улеснява запомнянето на команди според функционалното им предназначение.

Преди изпълнение изходната програма се превежда с помощта на програма за превод, наречена асемблер, на езика на кодовите комбинации - машинен език, в тази форма се поставя в паметта на MP и след това се използва при изпълнение на командата.


Методи за адресиране

Всички кодове на операнди (вход и изход) трябва да се намират някъде. Те могат да бъдат във вътрешните регистри на МП (най-удобният и бърз вариант). Те могат да се намират в системна памет(най-често срещаният вариант). И накрая, те могат да бъдат в I / O устройства (най-редкият случай). Местоположението на операндите се определя от кода на инструкцията. Има различни методи, чрез които кодът на инструкцията може да определи откъде да вземе входния операнд и къде да постави изходния операнд. Тези методи се наричат ​​методи за адресиране.

За MP KR580VM80 има следните методи за адресиране:

Незабавно;

Регистрирам;

непряк;

Стек.

Незабавно адресирането предполага, че операндът (входът) е в паметта непосредствено след кода на инструкцията. Операндът обикновено е константа, която трябва да бъде изпратена някъде, добавена към нещо и т.н. данните се съдържат във втория или втория и третия байт на командата, с младия байт данни във втория команден байт и старшия байт данни в третия команден байт.

Направо (известно още като абсолютно) адресиране предполага, че операндът (вход или изход) се намира в паметта на адреса, чийто код се намира вътре в програмата непосредствено след кода на инструкцията. Използва се в трибайтови команди.

Регистрирам адресирането предполага, че операндът (вход или изход) е във вътрешния MP регистър. Използва се в еднобайтови команди

Непряк (неявното) адресиране предполага, че вътрешният регистър на MP не е самият операнд, а неговият адрес в паметта.

Стек адресирането предполага, че командата не съдържа адрес. Адресиране към клетките на паметта чрез съдържанието на 16-битовия SP регистър (указател на стека).

Командна система

Командната система MP е пълен списък от елементарни действия, които MP е способен да изпълнява. MP управляван от тези команди изпълнява прости стъпки, като елементарна аритметика и логически операции, трансфер на данни, сравнение на две стойности и др. Броят на командите MP KR580VM80 - 78 (включително модификации 244).

Има следните групи команди:

Предаване на данни;

аритметика;

Главоблъсканица;

Команди за скок;

Команди за вход-изход, управление и работа със стека.


Символи и съкращения, използвани при описване на команди и писане на програми

Символ Намаляване
АДРЕС 16 битов адрес
ДАННИ 8-битови данни
ДАННИ 16 16 битови данни
ПРИСТАНИЩЕ 8-битов I/O адрес (I/O устройства)
БАЙТ 2 Втори команден байт
БАЙТ 3 Трети команден байт
R, R1, R2 Един от регистрите: A, B, C, D, E, H, L
RP Една от регистровите двойки: B - задава двойка самолети; D - задава чифт DE; H - определя чифт HL
RH Първи регистър на двойката
RL Втори регистър на двойката
Λ Булево умножение
V Булева добавка
Събиране по модул две
М Клетка с памет, чийто адрес определя съдържанието на регистровата двойка HL, т.е. M = (HL)

Структури на асемблер

Масивите, които разгледахме по-горе, са колекция от елементи от един и същи тип. Но често в приложенията има нужда да се вземе предвид определен набор от данни различен типкато някакъв единичен тип.

Това е много подходящо, например, за програми за бази данни, където е необходимо да се асоциира колекция от данни от различни типове с един обект.

Например, по-рано разгледахме листинг 4, който работи с масив от трибайтови елементи. Всеки елемент от своя страна беше два елемента от различни типове: еднобайтово поле за брояч и двубайтово поле, което можеше да носи малко повече информация, необходима за съхранение и обработка. Ако читателят е запознат с един от езиците на високо ниво, тогава той знае, че такъв обект обикновено се описва с помощта на специален тип данни - структури.

За да се подобри използваемостта на асемблерния език, този тип данни също беше въведен в него.

А-приори структура е тип данни, състоящ се от фиксиран брой елементи от различни типове.

За да използвате структури в програма, трябва да направите три неща:

    питам структурен шаблон .

    По същество това означава дефиниране на нов тип данни, който по-късно може да се използва за дефиниране на променливи от този тип.

    Дефинирайте структурен екземпляр .

    Този етап включва инициализирането на специфична променлива с предварително дефинирана (с помощта на шаблон) структура.

    Организирайте достъп до членовете на структурата .

Много е важно да разберете от самото начало каква е разликата между описаниеструктури в програмата и нейните определение.

описвам структура в програма означава само да се посочи нейната схема или модел; паметта не е разпределена.

Този шаблон може да се разглежда само като информация за преводача относно местоположението на полетата и тяхната стойност по подразбиране.

Дефинирайте структура означава да инструктира преводача да разпредели памет и да присвои символно име на тази област от паметта.

Можете да опишете структурата в програмата само веднъж и да я дефинирате произволен брой пъти.

Описание на шаблона на структурата

Декларацията на шаблона на структурата има следния синтаксис:

име_на_структура STRUC

име_на_структура ЗАВЪРШВА

Тук е поредица от директиви за описание на данни db, dw, dd, dqИ дт.

Техните операнди определят размера на полетата и евентуално началните стойности. Тези стойности вероятно ще инициализират съответните полета, когато структурата бъде дефинирана.

Както вече отбелязахме при описването на шаблона, не се разпределя памет, тъй като това е само информация за преводача.

Местоположениешаблонът в програмата може да бъде произволен, но, следвайки логиката на еднопроходния транслатор, той трябва да се намира преди мястото, където е дефинирана променливата с типа на тази структура. Тоест, когато се описва променлива с типа на някаква структура в сегмент от данни, нейният шаблон трябва да бъде поставен в началото на сегмента от данни или преди него.

Помислете за работа със структури, като използвате примера за моделиране на база данни от служители на определен отдел.

За простота, за да избегнем проблемите с преобразуването на информацията по време на въвеждане, ще се съгласим, че всички полета са символични.

Нека дефинираме структурата на записа на тази база данни със следния модел:

Дефиниране на данни със структурен тип

За да използвате структурата, описана с помощта на шаблона в програмата, е необходимо да дефинирате променлива с типа на тази структура. За това се използва следният синтаксис:

[име на променлива] име_на_структура

    име на променлива- идентификатор на променлива от даден структурен тип.

    Посочването на име на променлива не е задължително. Ако не е посочено, просто ще се задели област от паметта с размер на сумата от дължините на всички елементи на структурата.

    списък със стойности- разделен със запетая списък на първоначалните стойности на структурните елементи, оградени в ъглови скоби.

    Неговата задача също е по желание.

    Ако списъкът е непълен, тогава всички полета на структурата за дадената променлива се инициализират със стойности от шаблона, ако има такива.

    Разрешено е инициализиране на отделни полета, но в този случай липсващите полета трябва да бъдат разделени със запетаи. Липсващите полета ще бъдат инициализирани със стойности от структурния шаблон. Ако, когато дефинираме нова променлива с типа на тази структура, ние сме съгласни с всички стойности на полето в нейния шаблон (т.е. зададени по подразбиране), тогава просто трябва да напишете ъглови скоби.

    например: Виктор работник.

Например, нека дефинираме няколко променливи с вида на структурата, описана по-горе.

Структурни методи

Идеята за въвеждане на структурен тип във всеки език за програмиране е да се комбинират променливи от различни типове в един обект.

Езикът трябва да предоставя средства за достъп до тези променливи в конкретен екземпляр на структура. За да се препрати в команда към поле с някаква структура, се използва специален оператор - символ ". “ (точка). Използва се в следния синтаксис:

    адресен_израз- идентификатор на променлива от някакъв структурен тип или израз в скоби в съответствие със синтаксичните правила, посочени по-долу (фиг. 1);

    име_на_поле_на_структура- име на поле от шаблон на структура.

    Това всъщност също е адрес или по-скоро отместването на полето от началото на структурата.

Така че операторът " . " (точка) оценява израза

Ориз. 5. Синтаксис на адресен израз в оператор за достъп до структурно поле

Нека демонстрираме на примера на дефинираната от нас структура работник някои техники за работа със структури.

Например, извличане на брадвастойности на полето с възраст. Тъй като е малко вероятно възрастта на работоспособно лице да бъде повече от 99 години, след поставяне на съдържанието на това поле за символи в регистъра брадваще бъде удобно да го конвертирате в двоично представяне с командата aad.

Бъдете внимателни, защото поради принципа на съхранение на данни „нисък байт на нисък адрес“ще бъде поставена най-високата цифра на възрастта ал, а най-малкият в ах.

За да го коригирате, просто използвайте командата xchg al,ah:

mov ax,word ptr sotr1.age ;at al age sotr1

и е възможно така:

По-нататъшната работа с масив от структури се извършва по същия начин, както с едномерен масив. Тук възникват няколко въпроса:

Как да се справим с размера и как да организираме индексирането на елементите на масива?

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

След като размерът на екземпляр на структура стане известен, организирането на индексиране в масив от структури не е особено трудно.

например:

Как да копирам поле от една структура в съответното поле на друга структура? Или как да копирам цялата структура? Нека копираме полето иметрети служител в областта имепети служител:

mas_sotr работник 10 dup()

mov bx, отместване mas_sotr

mov si,(тип работник)*2;si=77*2

mov di,(тип работник)*4;si=77*4

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

От друга страна, напредъкът в развитието на софтуера и хардуера донякъде отпуска програмиста и доста често има ситуация, подобна на добре познатата поговорка за мухата и слона - за решаване на малък проблем се използват тежки инструменти участващи, чиято ефективност в общия случай е значителна само при изпълнение на сравнително големи проекти.

Наличието в езика на следните два типа данни вероятно се дължи на желанието на „домакинята“ да използва работната площ на масата (RAM) възможно най-ефективно при приготвяне на храна или за поставяне на продукти (програмни данни ).

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

Всяка машинна инструкция се състои от две части:

  • операционна - определяне "какво да се прави";
  • операнд - дефиниране на обекти за обработка, „какво да правя с“.

Машинната инструкция на микропроцесора, написана на асемблер, е един ред със следната синтактична форма:

етикет команда/директива операнд(и); коментари

При което задължително поле in line е команда или директива.

Етикетът, командата/директивата и операндите (ако има такива) са разделени с поне един интервал или знак за разделяне.

Ако дадена команда или директива трябва да бъде продължена на следващия ред, тогава се използва обратната наклонена черта: \.

По подразбиране асемблерният език не прави разлика между главни и малки букви в команди или директиви.

Примерни редове код:

Countdb 1 ;Име, директива, един операнд
mov eax,0 ;Команда, два операнда
cbw ; Екип

Етикети

Етикет на асемблерния език може да съдържа следните знаци:

  • всички букви от латинската азбука;
  • числа от 0 до 9;
  • специални знаци: _, @, $, ?.

Точка може да се използва като първи знак на етикет, но някои компилатори не препоръчват този знак. Запазени имена на асемблерни езици (директиви, оператори, имена на команди) не могат да се използват като етикети.

Първият знак в етикета трябва да е буква или специален знак (не число). Максималната дължина на етикета е 31 знака. Всички етикети, които са написани на ред, който не съдържа директива за асемблер, трябва да завършват с двоеточие: .

Екипи

Екип казва на преводача какво действие трябва да извърши микропроцесорът. В сегмент от данни команда (или директива) дефинира поле, работно пространство или константа. В кодов сегмент инструкция дефинира действие, като например преместване (mov) или добавяне (add).

директиви

Асемблерът има редица оператори, които ви позволяват да контролирате процеса на асемблиране и генериране на списък. Тези оператори се наричат директиви . Те действат само в процеса на сглобяване на програмата и за разлика от инструкциите не генерират машинни кодове.

операнди

Операнд – обект, върху който се изпълнява машинна команда или оператор на език за програмиране.
Една инструкция може да има един или два операнда или изобщо да няма операнди. Броят на операндите е имплицитно определен от кода на инструкцията.
Примери:

  • Няма операнди ret ;Return
  • Един операнд inc ecx ;Увеличение ecx
  • Два операнда добавят eax,12 ;Добавете 12 към eax

Етикетът, командата (директивата) и операндът не трябва да започват от конкретна позиция в низа. Въпреки това е препоръчително да ги напишете в колона за по-голяма четливост на програмата.

Операндите могат да бъдат

  • идентификатори;
  • низове от знаци, затворени в единични или двойни кавички;
  • цели числа в двоична, осмична, десетична или шестнадесетична система.
Идентификатори

Идентификатори – поредици от валидни знаци, използвани за обозначаване на програмни обекти като кодове на операции, имена на променливи и имена на етикети.

Правила за писане на идентификатори.

  • Идентификаторът може да бъде един или повече знака.
  • Като символи можете да използвате букви от латинската азбука, цифри и др специални символи: _, ?, $, @.
  • Идентификаторът не може да започва с цифра.
  • ID може да бъде с дължина до 255 знака.
  • Преводачът приема първите 32 знака от идентификатора и игнорира останалите.
Коментари

Коментарите са разделени от изпълнимия ред със знак; . В този случай всичко, което е написано след точка и запетая до края на реда, е коментар. Използването на коментари в програма подобрява нейната яснота, особено когато целта на набор от инструкции е неясна. Коментарът може да съдържа всякакви печатни знаци, включително интервали. Коментарът може да обхваща целия ред или да следва командата на същия ред.

Програмна структура на събранието

Една програма, написана на асемблер, може да се състои от няколко части, т.нар модули . Всеки модул може да дефинира един или повече сегменти от данни, стек и код. Всяка пълна програма на асемблерен език трябва да включва един главен или основен модул, от който започва нейното изпълнение. Един модул може да съдържа код, данни и сегменти от стека, декларирани със съответните директиви. Преди да декларирате сегменти, трябва да посочите модела на паметта с помощта на директивата .MODEL.

Пример за "нищоправеща" програма на асемблер:

686P
.МОДЕЛ ПЛАТ, STDCALL
.ДАННИ
.КОД
НАЧАЛО:

RET
КРАЙ НАЧАЛО

Тази програма съдържа само една микропроцесорна инструкция. Тази команда е RET. Осигурява правилното прекратяване на програмата. По принцип тази команда се използва за излизане от процедура.
Останалата част от програмата е свързана с работата на преводача.
.686P - Разрешени са команди за защитен режим Pentium 6 (Pentium II). Тази директива избира поддържания набор от инструкции за асемблер чрез указване на модела на процесора. Буквата P в края на директивата казва на преводача, че процесорът работи в защитен режим.
.MODEL FLAT, stdcall е плосък модел на паметта. Този модел памет се използва в операционната система Windows. stdcall
.DATA е програмен сегмент, съдържащ данни.
.CODE е програмен блок, съдържащ код.
START е етикет. В асемблера етикетите играят голяма роля, което не може да се каже за съвременните езици на високо ниво.
END START - край на програмата и съобщение до преводача, че програмата трябва да бъде стартирана от етикета START.
Всеки модул трябва да съдържа директива END, която маркира края на изходния код на програмата. Всички редове, които следват директивата END, се игнорират. Пропускането на директивата END генерира грешка.
Етикетът след директивата END казва на компилатора името на основния модул, от който започва изпълнението на програмата. Ако програмата съдържа един модул, етикетът след директивата END може да бъде пропуснат.

Структура на инструкциите на асемблерния език Програмирането на ниво машинни инструкции е минималното ниво, на което е възможно компютърно програмиране. Системата от машинни инструкции трябва да е достатъчна, за да изпълнява необходимите действия чрез издаване на инструкции към хардуера на машината. Всяка машинна инструкция се състои от две части: операционна част, която дефинира „какво да се направи“ и операнд, който дефинира обработващи обекти, тоест „какво да се направи“. Машинната инструкция на микропроцесора, написана на асемблер, е един ред, имащ следната форма: етикетна инструкция/директивен операнд(и); коментари Етикетът, командата/директивата и операндът са разделени с поне един знак за интервал или раздел. Операндите на инструкциите са разделени със запетаи.

Структура на инструкцията на асемблерния език Инструкцията на асемблерния език казва на компилатора какво действие трябва да извърши микропроцесорът. Директивите за асемблиране са параметри, посочени в текста на програмата, които засягат процеса на асемблиране или свойствата на изходния файл. Операндът определя началната стойност на данните (в сегмента с данни) или елементите, върху които трябва да се действа от инструкцията (в сегмента на кода). Една инструкция може да има един или два операнда или да няма операнди. Броят на операндите е имплицитно определен от кода на инструкцията. Ако командата или директивата трябва да бъдат продължени на следващия ред, тогава се използва обратната наклонена черта: "" . По подразбиране асемблерът не прави разлика между главни и малки букви в командите и директивите. Примери за директиви и команди Count db 1 ; Име, директива, един операнд mov eax, 0 ; Команда, два операнда

Идентификаторите са поредици от валидни знаци, използвани за обозначаване на имена на променливи и имена на етикети. Идентификаторът може да се състои от един или повече от следните знаци: всички букви от латинската азбука; числа от 0 до 9; специални знаци: _, @, $, ? . Като първи знак на етикета може да се използва точка. Запазени имена на асемблер (директиви, оператори, имена на команди) не могат да се използват като идентификатори. Първият символ на идентификатора трябва да е буква или специален знак. Максималната дължина на идентификатора е 255 знака, но преводачът приема първите 32 знака и игнорира останалите. Всички етикети, които са написани на ред, който не съдържа директива за асемблер, трябва да завършват с двоеточие ":". Етикетът, командата (директивата) и операндът не трябва да започват от конкретна позиция в низа. Препоръчително е да ги напишете в колона за по-голяма четливост на програмата.

Етикети Всички етикети, които са написани на ред, който не съдържа директива за асемблер, трябва да завършват с двоеточие ":". Етикетът, командата (директивата) и операндът не трябва да започват от конкретна позиция в низа. Препоръчително е да ги напишете в колона за по-голяма четливост на програмата.

Коментари Използването на коментари в програма подобрява нейната яснота, особено когато целта на набор от инструкции е неясна. Коментарите започват на всеки ред изходен модулсъс знак точка и запетая (;). Всички знаци вдясно от "; “ до края на реда са коментарите. Коментарът може да съдържа всякакви печатни знаци, включително "интервал". Коментарът може да обхваща целия ред или да следва командата на същия ред.

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

Модели на паметта Преди да декларирате сегменти, трябва да посочите модела на паметта с помощта на директива. MODEL модификатор memory_model, calling_convention, OS_type, stack_parameter Модели на паметта на основен език за асемблиране: Модел на паметта Кодово адресиране Адресиране на данни операционна системаПреплитане на код и данни МЪЛКО БЛИЗО MS-DOS Разрешено МАЛКО БЛИЗО MS-DOS, Windows Не СРЕДНО ДАЛЕЧНО БЛИЗО MS-DOS, Windows Не КОМПАКТНО БЛИЗО ДАЛЕЧНО MS-DOS, Windows Не ГОЛЯМО ДАЛЕЧНО MS-DOS, Windows Не ОГРОМНО ДАЛЕЧНО MS-DOS, Windows Не БЛИЗО до Windows 2000, Windows XP, разрешено за Windows ПЛОСК БЛИЗО до NT,

Модели на паметта Малкият модел работи само в 16-битови MS-DOS приложения. В този модел всички данни и код се намират в един физически сегмент. Размерът на програмния файл в този случай не надвишава 64 KB. Малкият модел поддържа един кодов сегмент и един сегмент от данни. Данните и кодът при използване на този модел се адресират като близо (близо). Средният модел поддържа множество кодови сегменти и един сегмент от данни, като всички връзки в кодовите сегменти се считат за далеч (далеч) по подразбиране, а връзките в сегмента с данни се считат за близки (близо). Компактният модел поддържа множество сегменти от данни, които използват далечно адресиране на данни (далеч), и един кодов сегмент, който използва близко адресиране на данни (близо). Големият модел поддържа множество кодови сегменти и множество сегменти от данни. По подразбиране всички препратки към код и данни се считат за далеч. Огромният модел е почти еквивалентен на модела с голяма памет.

Модели на паметта Плоският модел предполага несегментирана програмна конфигурация и се използва само на 32-битови операционни системи. Този модел е подобен на малкия модел по това, че данните и кодът се намират в един и същ 32-битов сегмент. Да се ​​разработи програма за плоския модел преди директивата. плосък модел трябва да постави една от директивите: . 386, . 486, . 586 или. 686. Изборът на директивата за избор на процесор определя набора от команди, налични при писане на програми. Буквата p след директивата за избор на процесор означава защитен режим на работа. Адресирането на данни и код е близо, като всички адреси и указатели са 32-битови.

модели с памет. MODEL модификатор memory_model, calling_convention, OS_type, stack_parameter Параметърът модификатор се използва за дефиниране на типове сегменти и може да приеме следните стойности: използване 16 (сегментите от избрания модел се използват като 16-битови) използване 32 (използват се сегменти от избрания модел като 32-битов). Параметърът calling_convention се използва, за да се определи как се предават параметрите при извикване на процедура от други езици, включително езици от високо ниво (C++, Pascal). Параметърът може да приема следните стойности: C, BASIC, FORTRAN, PASCAL, SYSCALL, STDCALL.

модели с памет. MODEL модификатор memory_model, calling_convention, OS_type, stack_parameter Параметърът OS_type е OS_DOS по подразбиране и на този моменттова е единствената поддържана стойност за този параметър. Параметърът stack_param е зададен на: NEARSTACK (SS регистър е равен на DS, данните и стековите региони са разположени в един и същ физически сегмент) FARSTACK (SS регистърът не е равен на DS, данните и стековите региони са разположени в различни физически сегменти). По подразбиране е NEARSTACK.

Пример за програма за "неправене на нищо". 686 P. МОДЕЛ АПАРАТ, STDCALL. ДАННИ. CODE START: RET END START START RET - микропроцесорна команда. Осигурява правилното прекратяване на програмата. Останалата част от програмата е свързана с работата на преводача. . 686 P - Разрешени са команди за защитен режим на Pentium 6 (Pentium II). Тази директива избира поддържания набор от инструкции за асемблер чрез указване на модела на процесора. . MODEL FLAT, stdcall - плосък модел на паметта. Този модел памет се използва в операционната система Windows. stdcall е конвенцията за извикване на процедурата, която трябва да се използва.

Пример за програма за "неправене на нищо". 686 P. МОДЕЛ АПАРАТ, STDCALL. ДАННИ. КОД START: RET END START . DATA - програмен сегмент, съдържащ данни. Тази програма не използва стека, така че сегментирайте. STACK липсва. . КОД - сегмент от програмата, съдържащ кода. СТАРТ - етикет. END START - край на програмата и съобщение до компилатора, че програмата трябва да се стартира от етикета START. Всяка програма трябва да съдържа директива END, която маркира края на изходния код на програмата. Всички редове, които следват директивата END, се игнорират Етикетът след директивата END казва на компилатора името на основния модул, от който започва изпълнението на програмата. Ако програмата съдържа един модул, етикетът след директивата END може да бъде пропуснат.

Преводачи на асемблерни езици Преводачът е програма или технически средства A, който преобразува програма на един от езиците за програмиране в програма на целевия език, наречен обектен код. В допълнение към поддръжката на мнемоника за машинни инструкции, всеки преводач има свой собствен набор от директиви и макроси, често несъвместими с нищо друго. Основните видове преводачи на асемблерни езици: MASM (Microsoft Assembler), TASM (Borland Turbo Assembler), FASM (Flat Assembler) - свободно разпространяван многопроходен асемблер, написан от Tomasz Gryshtar (полски), NASM (Netwide Assembler) - безплатен асемблер за Архитектури на Intel x86 е създаден от Simon Tatham с Julian Hall и в момента се разработва от малък екип за разработка на Source. Ковачница. нето.

Src="https://present5.com/presentation/-29367016_63610977/image-15.jpg" alt="Програмен превод в Microsoft Visual Studio 2005 1) Създайте проект, като изберете Файл->Нов->Проект меню И"> Трансляция программы в Microsoft Visual Studio 2005 1) Создать проект, выбрав меню File->New->Project и указав имя проекта (hello. prj) и тип проекта: Win 32 Project. В !} допълнителни опциисъветника за проекти, за да посочите „Празен проект“.

Src="https://present5.com/presentation/-29367016_63610977/image-16.jpg" alt="Превод на програма в Microsoft Visual Studio 2005 2) В дървото на проекта (View->Solution Explorer) добавете"> Трансляция программы в Microsoft Visual Studio 2005 2) В дереве проекта (View->Solution Explorer) добавить файл, в котором будет содержаться текст программы: Source. Files->Add->New. Item.!}

Превод на програмата в Microsoft Visual Studio 2005 3) Изберете типа файл Code C++, но посочете името с разширението. asm:

Превод на програмата в Microsoft Visual Studio 2005 5) Задаване на опции на компилатора. Изберете по десен бутонвъв файла на проекта на менюто с персонализирани правила за изграждане...

Превод на програмата в Microsoft Visual Studio 2005 и в появилия се прозорец изберете Microsoft Macro Assembler.

Превод на програмата в Microsoft Visual Studio 2005 Отбележете с десен бутон във файла hello. asm на дървото на проекта от менюто Properties и задайте General->Tool: Microsoft Macro Assembler.

Src="https://present5.com/presentation/-29367016_63610977/image-22.jpg" alt="Превод на програма в Microsoft Visual Studio 2005 6) Компилирайте файла, като изберете Build->Build hello.prj ."> Трансляция программы в Microsoft Visual Studio 2005 6) Откомпилировать файл, выбрав Build->Build hello. prj. 7) Запустить программу, нажав F 5 или выбрав меню Debug->Start Debugging.!}

Програмиране на ОС Windows програмиранев OC Windows се основава на използването на API функции (интерфейс на приложната програма, т.е. интерфейс софтуерно приложение). Техният брой достига 2000. Програмата за Windows до голяма степен се състои от такива разговори. Цялото взаимодействие с външни устройства и ресурси на операционната система се осъществява, като правило, чрез такива функции. операционна Windows системаизползва модел с плоска памет. Адресът на всяко място в паметта ще се определя от съдържанието на един 32-битов регистър. Съществуват 3 вида програмни структури за Windows: диалогова (основният прозорец е диалогова), конзолна или безпрозоречна структура, класическа структура (прозорец, рамка).

Обадете се Функции на Windows API В помощния файл всяка API функция е представена като тип име_на_функция (FA 1, FA 2, FA 3) Тип – тип върната стойност; FAX – списък на формалните аргументи в техния ред, например int Съобщение. Кутия (HWND h. Wnd, LPCTSTR lp. Текст, LPCTSTR lp. Надпис, UINT u. Тип); Тази функцияпоказва прозорец със съобщение и бутон(и) за изход. Значение на параметрите: h. Wnd - манипулатор на прозореца, в който ще се появи прозорецът за съобщения, lp. Text - текстът, който ще се появи в прозореца, lp. Надпис - текст в заглавието на прозореца, u. Тип - тип прозорец, по-специално можете да посочите броя на бутоните за изход.

Извикване на Windows API функции int Message. Кутия (HWND h. Wnd, LPCTSTR lp. Текст, LPCTSTR lp. Надпис, UINT u. Тип); Почти всички функционални параметри на API всъщност са 32-битови цели числа: HWND е 32-битово цяло число, LPCTSTR е 32-битов указател на низ, UINT е 32-битово цяло число. Суфиксът "A" често се добавя към името на функциите, за да преминете към по-нови версии на функции.

Извикване на Windows API функции int Message. Кутия (HWND h. Wnd, LPCTSTR lp. Текст, LPCTSTR lp. Надпис, UINT u. Тип); Когато използвате MASM, трябва да добавите @N N в края на името - броят байтове, които предадените аргументи заемат в стека. За функциите на API на Win 32 това число може да се дефинира като броя на аргументите n по 4 (байтове във всеки аргумент): N=4*n. За извикване на функция се използва инструкцията CALL на асемблера. В този случай всички аргументи на функцията се предават към нея чрез стека (PUSH команда). Посока на преминаване на аргумента: ОТЛЯВО НАДЯСНО - ОТДОЛУ НАГОРЕ. Аргументът u ще бъде избутан първо в стека. Тип. Обадете се определена функцияще изглежда така: CALL Съобщение. кутия. [имейл защитен]

Извикване на Windows API функции int Message. Кутия (HWND h. Wnd, LPCTSTR lp. Текст, LPCTSTR lp. Надпис, UINT u. Тип); Резултатът от изпълнението на която и да е API функция обикновено е цяло число, което се връща в EAX регистъра. Директивата OFFSET е "сегментно отместване" или, в езикови термини от високо ниво, "указател" към началото на низ. Директивата EQU, подобно на #define в C, дефинира константа. Директивата EXTERN казва на компилатора, че дадена функция или идентификатор е външен за модула.

Пример за програмата "Здравейте всички!" . 686 P. МОДЕЛ АПАРАТ, STDCALL. STACK 4096. DATA MB_OK EQU 0 STR 1 DB "Моята първа програма", 0 STR 2 DB "Здравейте на всички!", 0 HW DD ? ВЪНШНО съобщение. кутия. [имейл защитен]: БЛИЗО ДО. CODE START: PUSH MB_OK PUSH OFFSET STR 1 PUSH OFFSET STR 2 PUSH HW CALL Съобщение. кутия. [имейл защитен] RET END START

Директивата INVOKE Преводачът на езика MASM също прави възможно опростяването на извикването на функция с помощта на макро инструмент - директивата INVOKE: функция INVOKE, параметър1, параметър2, ... Няма нужда да добавяте @16 към извикването на функция; параметрите са написани точно в реда, в който са дадени в описанието на функцията. макросите на транслатора избутват параметри в стека. за да използвате директивата INVOKE, трябва да имате описание на прототипа на функцията, използвайки директивата PROTO във формата: Съобщение. кутия. A ПРОТО: DWORD, : DWORD

Обща информация за асемблерния език

Символният асемблер позволява до голяма степен да се премахнат недостатъците на машинното програмиране.

Основното му предимство е, че в асемблерния език всички програмни елементи са представени в символна форма. Трансформирането на имена на символни команди в техните двоични кодове е отговорност на специална програма- асемблер, който освобождава програмиста от трудоемка работа и елиминира неизбежните грешки.

Символичните имена, въведени при програмиране на асемблер, като правило отразяват семантиката на програмата, а съкращението на командите - тяхната основна функция. Например: PARAM - параметър, TABLE - таблица, MASK - маска, ADD - събиране, SUB - изваждане и т.н. н. Такива имена се запомнят лесно от програмиста.

За програмиране на асемблер е необходимо да имате сложни инструменти, отколкото за програмиране на машинен език: имате нужда от компютърни системи, базирани на микрокомпютри или компютри с набор периферни устройства(буквено-цифрова клавиатура, символен дисплей, флопидисково устройство и принтер), както и резидентни или крос-програмни системи за необходимите типове микропроцесори. Асемблерният език ви позволява ефективно да пишете и дебъгвате много по-сложни програми от машинния език (до 1 - 4 KB).

Асемблиращите езици са машинно ориентирани, т.е. зависят от машинния език и структурата на съответния микропроцесор, тъй като те присвояват специфично символно име на всяка микропроцесорна инструкция.

Асемблерните езици осигуряват значително увеличение на производителността на програмистите в сравнение с машинните езици и в същото време запазват способността да използват всички софтуерно достъпни хардуерни ресурси на микропроцесора. Това позволява на квалифицирани програмисти да пишат програми, които се изпълняват за по-кратко време и заемат по-малко памет от програми, написани на език от високо ниво.

В тази връзка почти всички програми за управление на I / O устройства (драйвери) са написани на асемблер, въпреки наличието на доста голям набор от езици на високо ниво.

Използвайки асемблер, програмистът може да зададе следните параметри:

мнемоника (символно име) на всяка команда от машинния език на микропроцесора;

стандартен форматза редове на програма, описана в асемблер;

формат за уточняване различни начиниопции за адресиране и командване;

формат за указване на символни константи и константи от целочислен тип в различни бройни системи;

псевдокоманди, които контролират процеса на асемблиране (превод) на програмата.

В асемблерния език програмата се записва ред по ред, т.е. за всяка инструкция се отделя един ред.

За микрокомпютри, изградени на базата на най-често срещаните типове микропроцесори, може да има няколко варианта на асемблерния език, но обикновено има едно практическо разпространение - това е така нареченият стандартен асемблерен език

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

Всяка машинна инструкция се състои от две части:

операционна - определяща "какво да се направи";

· операнд - дефиниране на обработващи обекти, "какво да се прави с".

Машинната инструкция на микропроцесора, написана на асемблер, е един ред със следната синтактична форма:

операнд(и) на команда/директива за етикет; коментари

В този случай задължително поле в ред е команда или директива.

Етикетът, командата/директивата и операндите (ако има такива) са разделени с поне един интервал или знак за разделяне.

Ако дадена команда или директива трябва да бъде продължена на следващия ред, тогава се използва обратната наклонена черта: \.

По подразбиране асемблерният език не прави разлика между главни и малки букви в команди или директиви.

Директно адресиране: Ефективният адрес се определя директно от полето за отместване на машинната инструкция, което може да бъде с размер 8, 16 или 32 бита.

mov eax, сума; eax = сума

Асемблерът заменя sum със съответния адрес, съхранен в сегмента с данни (по подразбиране, адресиран от регистър ds) и поставя стойността, съхранена на адрес sum в регистър eax.

индиректно адресиранена свой ред има следните видове:

Непряка основна (регистрова) адресация;

Непряка основна (регистрова) адресация с отместване;

· индиректно индексно адресиране;

· индиректно базово индексно адресиране.

Непряка основна (регистрова) адресация.С това адресиране ефективният адрес на операнда може да бъде във всеки от регистрите с общо предназначение, с изключение на sp / esp и bp / ebp (това са специфични регистри за работа със сегмент на стека). Синтактично в инструкция този режим на адресиране се изразява чрез затваряне на името на регистъра в квадратни скоби.

mov eax, ; eax = *esi; *esi стойност на адрес esi