Mov DX, offset message
Int 21h Mov SI, 0 Mov CX, 3 m1: lea DX, st1[SI] Int 21h Add SI, 9 Loop m1 Ret message DB “hello”,0dh,0ah,”$” Tst struc ; описание типа структуры s DB “student ”,”$” f DB “Ivanov “,”$” i DB “Ivan “,”$” Tst ends st1 tst < > End start Prim3.asm – обращение к полям структур: цикл в цикле для работы с 2-мя записями .model tiny .code org 100h ; обход блока PSP Start: mov AH, 9 mov DX, offset message int 21h lea BX, st1 ; адрес первой записи в BX mov CX, 2 ; количество повторений внешнего цикла m2: push CX mov SI, 0 mov CX, 3 ; количество повторений внутреннего цикла m1: push CX lea DX, [BX] [SI] ; адресация по базе с индексированием int 21h add SI, 9 ; переход к следующему полю pop CX loop m1 add BX, type tst ; переход к следующей записи pop CX loop m2 ret message DB “hello”,0dh,0ah,”$” tst struc ; описание типа структуры s DB ? f DB ? i DB ? tst ends st1 tst < “student $”,”Inanov $”,”Ivan, $” > st2 tst < “student $”,”Petrov $”,”Petr, $” > end start Результат работы программы: hello student Ivanov Ivan, student Petrov Petr
10) Записи в Ассемблере, их описание и использование. Запись – это упакованные данные, которые занимают не отдельные, полные ячейки памяти (байты или слова), а части ячеек. Запись в Ассемблере занимает байт или слово (другие размеры ячеек для записи не допускаются), а поля записи - это группы последовательно расположенных битов этой ячейки (байта или слова). Поля должны быть прижаты друг к другу, между ними не должно быть пробелов. Размер поля в битах может быть любым, но в сумме размер всех полей не должен быть больше 16. Сумма размеров всех полей называется размером записи. Если размер записи меньше 8 битов, то под запись 1 байт, если 8<x<=16, то – 2 байта. Если сумма полей меньше байта или двух байт, то поля прижимаются к правой границе ячейки, оставшиеся левые биты равны нулю, но к записи не относятся и не рассматриваются. Поля имеют имена, но обращаться к ним по именам нельзя, так как наименьший адресуемый элемент памяти это байт. Для работы с записью необходимо описать вначале тип записи, а затем описать переменные этого типа. Описание типа может располагаться в любом месте программы, но до описания переменных этого типа. Директива описания типа записи имеет вид: <имя типа записи > record <поле> {, <поле>} <поле> :: = <имя поля> : <размер> [= <выражение>] Здесь <размер> и <выражение> - это константные выражения. <размер> определяет размер поля в битах, <выражение> определяет значение поля по умолчанию. Знак ? не допускается. Например: графическое представление TRec record A : 3, B : 3 = 7 7 6 А B имена полей 0 7 3 3 размер в битах TData record Y : 7, M : 4, D : 5 Y M D 0 0 0 7 4 5 Год, записанный двумя последними цифрами 26 < Y max = 99 < 27 Имена полей, также как и в структурах, должны быть уникальными в рамках всей программы, в описании они перечисляются слева направо. <выражение> может отсутствовать, если оно есть, то его значение должно умещаться в отведенный ему размер в битах. Если для некоторого поля выражение отсутствует, то его значение по умолчанию равно нулю, не определенных полей не может быть. Определенное директивой record имя типа (Trec, TData) используется далее как директива для описания переменных –записей такого типа. имя записи имя типа записи <начальные значения>, угловые скобки здесь не метасимволы, а символы языка, внутри которых через запятую указываются начальные значения полей. Начальными значениями могут быть: 1) константное выражение, 2) знак ?, 3) пусто В отличие от структуры, знак ? определяет нулевое начальное значение, а «пусто», как и в структуре, определяет начальное значение равным значению по умолчанию. Например: Rec1 TRec < 3, > ; 7 6 A B 0 0 0 3 7 Rec2 TRec < , ? > 0 0 0 0 Dat1 TData < 46, 9, 4 > ; 15 Y M D 0 46 9 4 также , как и для структур: Dat1 TData < 00, , > == Dat1 TData < 00 > Dat2 TData < , , > == Dat2 TData < > Одной директивой можно описать массив записей, используя несколько параметров в поле операндов или конструкцию повторения, например, MDat TData 100 Dup ( < > ) Описали 100 записей с начальными значениями, равными принятыми по умолчанию. Со всей записью в целом можно работать как обычно с байтами или со словами, т.е. можно реализовать присваивание Rec1 = Rec2 : Mov AL, Rec2 Mov Rec1, AL Для работы с отдельными полями записи существуют специальные операторы width и mask. width <имя поля записи> width <имя записи или имя типа записи> Значением оператора width является размер в битах поля или всей записи в зависимости от операнда. оператор mask имеет вид: Mask <имя поля записи> Mask <имя записи или имя типа записи> Значением этого оператора является «маска» - это байт или слово, в зависимости от размера записи, содержащее единицы в тех разрядах, которые принадлежат полю или всей записи, указанных в качестве операнда, и нули в остальных, не используемых разрядах. Например: mask A = 00111000b mask B = 00000111b mask Y = 1111111000000000b mask Rec1 = mask TRec = 00111111b Этот оператор используется для выделения полей записи. Пример. Выявить всех родившихся 1-го числа, для этого придется выделять поле D и сравнивать его значение с 1-ей. m1: ------------------------- mov AX, Dat1 and AX, mask D cmp AX, 1 je yes no: --------------------- --------------------- При работе с записями, ассемблер имени любого поля приписывает в качестве значения число, на которое нужно сдвинуть вправо это поле, чтобы оно оказалось прижатым к правой границе ячейки, занимаемой записью. Так значением поля D для записи типа TData является ноль, для поля M – 5, для поля Y – 9. Значения имен полей используются в командах сдвига, например, определить родившихся в апреле можно так: m1: ---------------------------- mov AX, Dat ; AX = Y M D and AX, mask M ; AX = 0 M 0 mov CL, M ; CL = 5 shr AX, CL ; AX = 0 0 M cmp AX, 4 ; M = 4 ? je yes no: ------------------ jmp m1 ---------------------- yes: --------------------------
28) Работа со строками переменной длины в Ассемблере. Строка в языке Ассемблера может быть реализована по аналогии с тем, как это сделано в языке С/С++ и как в языке Паскаль. В С/С++ за последним символом строки располагают специальный символ, являющийся признаком конца строки. Изменение длины строки сопровождается переносом этого символа. Недостатком такого представления строк переменной длины является то, что, например, для сравнения строк S1 и S2, длиной 500 и 1000 символов необходимо выполнить может быть 500 сравнений, хотя зная, что длина их различна, их можно было совсем не сравнивать. В Паскале строка представляется так: S n s1 s2 …….. Sn … Где n – текущая длина. Сколько места необходимо отводить под значение длины строки n – зависит от максимально возможной длины. Если она может состоять не более, чем из 255 символов, то под n достаточно одного байта. Тогда текущая длина строки содержится по адресу S, а ее i-ый символ по адресу S + i. Строку из 200 символов можно описать так: S DB 201 dup (?) Пример 3. Удалить из строки S первое вхождение символа звездочка. -------------------------------------------------- ; поиск ‘ * ‘ push DS ; pop ES ; (ES) = (DS) lea DI, S + 1; ES:DI = адресу S[1] CLD ; просмотр вперед mov CL, S ; текущая длина строки mov CH, 0 ; в CX mov AL, ‘ * ‘ repne scasb ; поиск ‘ * ‘ в S jne finish ; ‘ * ‘ в S нет на метку finish ; удаление ‘ * ‘ из S, сдвинуть S на 1 символ Si = Si+1 mov SI, DI ; DS:SI = адресу, откуда начинать пересылку dec DI ; ES:DI = куда пересылать rep movsb ; сдвиг «хвоста» S на 1 позицию влево dec S ; уменьшить на 1 текущую длину finish --------------------------
24) Макросредства в языке Ассемблере – блоки повторения. Макросредства называют самым мощным средством прогрммирования в Ассемблере. Они позволяют изменять, модифицировать текст программы на Ассемблере в процессе выполнения программы, если используются директивы условного ассемблирования. К макросредствам относят: блоки повторений, макросы, директивы условной генерации. Программы, написанные на макроязыке, транслируются в два этапа. Сначала она переводится на «чистый» язык Ассемблера, т.е. преобразуется к виду, в котором нет никаких макросредств, этот этап называют макрогенерацией. Затем выполняется ассемблирование - перевод в машинные коды (т.е. на первом этапе раскрываются все макросредства, то есть текст становится без макросов, - макрогенерация или предпроцессорная обработка, а на втором этапе – перевод в коды машины). Макрогенерацию называют ещё препроцессорной обработкой. Блоки повторения в процессе макрогенерации заменяются указанной последовательностью команд столько раз, сколько задано в заголовке блока, причем набор команд может повторяться в неизменном или модифицированном виде, в зависимости от вида заголовка блока. Набор команд повторяется n раз в том месте программы, где указан блок повторения. Макросы более похожие на ПП. Аналогично ПП существует описание макроса и обращение к нему. Описание макроса называют макроопределением, а обращение - макрокомандой. Процесс замены макрокоманды на макрос - макроподстановкой, а результат этой подстановки - макрорасширением. Макроопределение не порождает никаких машинных команд, оно должно предшествовать первой макрокоманде, использующей это макроопределение, и может располагаться как непосредственно в тексте программы, так и может быть подключено из другого файла с помощью директивы INCLUDE <имя файла>. Основное отличие макроса от процедуры заключается, во-первых, в том, что при обращении к ПП управление передаётся на участок памяти, в котором содержится описание ПП, а при обращении к макросу его тело (макроопределение) вставляется на место макрокоманды, т.е. сколько раз мы обратимся к макросу, сколько макрокоманд будет в программе, столько раз повторится макроопределение, вернее, макрорасширение. Макрос «размножается», увеличивая размер программы. Таким образом, применение процедур дает выигрыш по памяти, но использование макросов дает выигрыш по времени, т.к. нет необходимости передавать управление в ПП и обратно (CALL и RET), а также организовывать передачу параметров. Рекомендация: если повторяются большие фрагменты программ, лучше использовать процедуры, если относительно небольшие, то макросы. Второе отличие заключается в том, что текст процедуры неизменен, а содержание макрорасширения зависит от параметров макрокоманды, если используются директивы условной генерации, и тогда это существенно. Общий вид блока повторений: <заголовок> <тело> Endm <тело> - любое количество любых операторов, предложений, в том числе и блоков повторений. endm определяет конец тела блока. Количество повторений тела и способ модификаций тела блока зависит от заголовка. Возможны следующие заголовки: 1) REPT n ; n - константное выражение Оно может быть вычислено на этапе макрогенерации, в результате которого n копий тела блока записывается в данном месте программы на Ассемблере. Например: В исходном тексте После макрогенерации на этом месте N EQU 8 N EQU 8 REPT N-6 DB 0,1 DB 0,1 DW ? DW ? DB 0,1 Еndm DW ? Для создания массива с начальными значениями от 0 до OFFH достаточно написать блок повторений: n = 1 mas DB 0 ;имя массива mas Rept 255 ;начало блока DB n n = n + 1 Endm 2) Второй вид заголовка: IRP P , <V1,V2,…Vk> ;< и > обязательные символы <тело> ;тело повторяется k раз так, что в i-той копии Еndm формальный параметр Р замещается фактическим параметром Vi. Формальный параметр Р - это локальное имя, не имеющее смысла вне блока. Если оно совпадает с именем другого какого- либо объекта программы, то в теле блока это просто имя, а не этот объект. Например:После макрогенерации 1) IRP reg, <AX, BX, CX, SI> push AX Push reg push BX Endm push CX Push SI
2) IRP BX , <5,7,9> add AX , 5 add AX, BX → add AX , 7 Endm add AX , 9 Здесь ВХ - символическое имя, но не имя регистра ВХ. Причём, замена формального параметра на фактический - это просто текстовые замены, один участок программы Р заменяется на другой – Vi , т.е. Р может обозначать любую часть предложения или все предложение, лишь бы после замены Р на Vi получилось правильное предложение языка Ассемблер. 3) IRP R , <dec word ptr, L: inc word ptr> R W dec word ptr W jmp M → jmp M
Популярное: Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация... Почему стероиды повышают давление?: Основных причин три... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (1905)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |