Мегаобучалка Главная | О нас | Обратная связь


Assume cs: cseg, ds:dseg, ss:sseg



2018-07-06 690 Обсуждений (0)
Assume cs: cseg, ds:dseg, ss:sseg 0.00 из 5.00 0 оценок




Start proc far

Push DS ; для связи

Push AX ; с ОС

18. movBX, Dseg ;загрузка адреса сегмента данных

19. movDS, BX ;в регистр DS

Call main

Ret

Start endp

Main proc near

Mov BX, offset Dan

25. movCX, 4 ;количество повторений внешнего цикла

Nz1: push CX

27. movDL, 0 ;счетчик нулей в строке матрицы

Mov SI, 0

29. movCX, 5 ;количество повторений внутреннего цикла

Nz2: push CX

31. cmp byte ptr [BX+SI], 0

Jnemz

33. movbyteptr [BX+SI], 0FFh ; увеличили на единичку

Inc DL

Mz: inc SI

Pop CX

Kz2: loop nz2

38. addDL, ‘0’ ;вывод на экран

39. mov AH, 6 ;количества нулей

Int 21h

41. addBX, 5 ;переход к следующей строке матрицы

Pop CX

Kz1: loop nz1

Ret

Main endp

Cseg ends

End start

Задача решена с помощью двух вложенных циклов, во внутреннем осуществляется просмотр элементов текущей строки (32-39), увеличение счетчика нулей и пересылка константы 0FFh в байт, содержащий ноль. Во внешнем цикле осуществляется переход к следующей строке очисткой регистра SI (строка 30 ) и увеличением регистра BX на количество элементов в строке (40).

Физически последняя команда программы (49) в качестве параметра указывает метку команды, с которой необходимо начинать выполнение программы.

Директива title задает заголовок каждой странице листинга, заголовок может содержать до 60 символов.

Директива page устанавливает количество строк на странице листинга – 1-й параметр (здесь он отсутствует, значит, берется значение по умолчанию 57) и количество символов в каждой строке (здесь 132, возможно от 60 до 132, по умолчанию – 80).

Pageбезпараметров осуществляет перевод печати на новую страницу и увеличение на 1 номера страницы листинга.Эти директивы могут отсутствовать.

Работа с массивами:

Массивы в языке Ассемблер описываются директивами определения данных, возможно с использование конструкции повторения DUP.

Например, xDW 30 dup ( ? )

Так можно описать массив x, состоящий из 30 элементов длиной в слово, но в этом описании не указано как нумеруются элементы массива, т.е. это может быть x[0..29] и x[1..30] и x[k..29+k].

Значит, в процессе программирования мы можем их нумеровать от любого числа: от Kдо K +1. Если в задаче жестко не оговорена нумерация элементов, то в Ассемблере удобнее считать элементыот нуля, тогда адрес любого элемента будет записываться наиболее просто:

адрес (x[i]) = x + (type x) * i

В общем виде, когда первый элемент имеет номер k , для одномерного массива будет: адрес (x[i]) = x + (typex) * (i – k)

Для двумерного массива - A[0..n-1, 0..m-1]адрес (i,j) – го элемента можно вычислить так:

адрес (A[i,j]) = A + m * (type A) * i + (type A) *j

С учетом этих формул для записи адреса элемента массива можно использовать различные способы адресации.

Для описанного выше массива слов, адрес его i-го элемента равен:

x + 2*i = x + type (x) * i,

Т.е. адрес состоит из двух частей: постоянной x и переменной 2 * i, зависящей от номера элемента массива. Логично использовать адресацию прямую с индексированием:

x – смещение, а 2*i – в регистре модификаторе SI или DIx[ i ]

Для двумерного массива, например:

A DDnDUP (mDup (?) ); A[0..n - 1, 0..m - 1] получим

адрес (A[ i,j ]) = A + m * 4 * i + 4 *j,

Т.е. имеем в адресе постоянную часть А и две переменных m * 4 * iи 4 *j ,которые можно хранить в регистрах. Два модификатора есть в адресации по базе с индексированием, например: A[BX][DI].

Пример:

Фрагмент программы, в которой в регистр AL записывается количество строк матрицы XDB 10 dup (20 dup (?) ), в которых первый элемент повторяется хотя бы один раз.

----------------------------------

movAL, 0; количество искомых строк

movCX, 10 ;количество повторений внешнего цикла

movBX, 0 ;начало строки 20*i

M1: pushCX

movAH, X[BX] ;1-й элемент строки в AH

movCX, 19 ;количество повторений внутреннего цикла

movDI, 0 ;номер элемента в строке ( j )

m2: inc DI; j = j + 1

cmp AH, X[BX][DI]; A[i,0] = A[i,j]

loopnem2 ;первый не повторился? Переход на m2

jneL ;не было в строке равных первому? Переход на L

incAL ;первый повторился, увеличиваем счетчик строк

L: popCX; восстанавливаем CX для внешнего цикла

addBX, 20 ;в BX начало следующей строки

Loopm1

------------------------------

Команды побитовой обработки данных:

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

Логические команды:and, or, xor, not.

Для всех логических команд, кроме not, операнды одновременно не могут находиться в памяти, OF = CF = 0, AF – не определен, SF, ZF, PF определяются результатом команды.

1. andOP1, OP2; (OP1) логически умножается на (OP2), результат ®OP1

Пример: (AL) = 1011 0011, (DL) = 0000 1111,

and AL, DL; (AL) = 0000 0011

Второй операнд называют маской. Основным назначением команды and является установка в ноль с помощью маски некоторых разрядов первого операнда. Нулевые разряды маски обнуляют соответствующие разряды первого операнда, а единичные оставляют соответствующие разряды первого операнда без изменения. Маску можно задавать непосредственно в команде и можно извлекать из регистра или памяти.

Например:

· andCX, 0FFh; маской является константа

· andAX, CX; маска содержится в регистре СХ, а обнуляются какието разряды регистра АХ

· andAX, TOT; маска в ОП по адресу (DS) (смещенное на 4 разряда влево)+ (значение переменной)TOT

· andCX, TOT[BX+SI] ; маска лежит в ОП по адресу (DS) (смещенное на 4 разряда влево)+ (BX) + (SI) + TOT

· andTOT[BX+SI], CX; маска находится в СХ, а обнуляются некоторые разряды в памяти

· andCL, 0Fh; в ноль устанавливаются старшие 4 разряда регистра CL

2. Команда – orOP1, OP2;к содержимому первого операнда логически прибавляется содержимое второго операнда и результат посылается по адресу первого операнда. Второй операнд это тоже маска, которая используется для установки в единицу заданных разрядов первого операнда.

Например:

(AL) = 1011 0011; (DL) = 0000 1111; orAL, DL ; (AL) = 1011 1111

В команде могут использоваться различные операнды:

or CX, 00FFh ; or TAM, AL ; or TAM[BX][DX], CX

Если во всех битах результата будет 0, то ZF = 1.

3. Команда исключающее или - xorOP1, OP2; 1 xor 1 = 0, 0 xor 0 = 0,

в ост.сл. = 1

Например: (AL) = 1011 0011, маска = 000 01111

xorAL, 0Fh; (AL) = 1011 1100

4. Команда notOP; результат – инверсия значения операнда

Если (AL) = 0000 0000, not AL; (AL) = 1111 1111

Унарная команда notзначения флагов не изменяются.

Примеры.

1) xorAX, AX ; обнуляет регистр AX быстрее, чем mov и sub

2) xorAX, BX; меняет местами значения AX и BX

xorBX, AX ; быстрее, чем команда

xor AX, BX; xchgAX, BX

Пример:

Определить количество задолжников в группе из 20 студентов. Информация о студентах содержится в массиве байтов

XDB 20DUP (?), причем в младших 4 битах каждого байта содержатся оценки, т.е. 1 – сдал экзамен, 0 – «хвост».

В DL сохраним количество задолжников.

-----------------------------

Mov DL, 0

mov SI, 0 ; i = 0

movCX, 20 ;количество повторений цикла

nz: movAL, X[SI]

andAL, 0Fh ;обнуляем старшую часть байта

xorAL, 0Fh ;

jzm ;ZF = 1, хвостов нет, передаем на повторение цикла

incDL; увеличиваем количество задолжников

m: incSI;переходим к следующему студенту

Loopnz

add DL, “0”

Mov AH, 6

Int 21h

--------------------------

Команды сдвига:

Формат команд арифметического и логического сдвига можно представить так:

sXYOP1, OP2 ; <комментарий>

Здесь X - H или A, Y – L или R; OP1 – R или M, OP2 – D или CL.

И для всех команд сдвига в CL используются только 5 младших разрядов, принимающих значения от 0 до 31. При сдвиге на один разряд:

- SHL - логическом сдвиге влево: при сдвиге на один разряд сдвигаемый разряд попадает во флажок CF, а на место сдвигаемого разряда ставится в ноль;

- SHR -логический сдвиг вправо: сдвигаемый разряд заменяется нулем, а тот который выходит за пределы изменяет содержимое флага CF;

- SAL – арифметический сдвиг влево:ничем не отличается от SHL

- SAR – арифметический сдвиг вправо: отличается от SHR тем, что не нулем заполняется, а знаковым разрядом;

Здесь знаковый бит распространяется на сдвигаемые разряды.

Например, (AL) = 1101 0101

sarAL, 1 ; (AL) = 1110 1010 иCF = 1

Сдвиги повышенной точности для i186 и выше:

shrd OP1, OP2, OP3 ;

shld OP1, OP2, OP3 ;

Содержимое первого операнда (OP1) сдвигается на количество разрядов определенное третьим операндов (OP3) разрядов также, как и в командах shr и shl но бит, вышедший за разрядную сетку, не обнуляется, а заполняется содержимым второго операнда, которым может быть только регистр.

Циклические сдвиги:

Команда ROL– циклический сдвиг влево: сдвигаем разряд попадает в CF и циклически переносится сдвигаемый влево(вправо в случае ROR).

Циклические сдвиги с переносом содержимого Флажка CF:

Для всех команд сдвига флаги ZF, SF, PF устанавливаются в соответствии с результатом. AF – не определен.OF – не определен при сдвигах на несколько разрядов, при сдвиге на 1 разряд в зависимости от команды:

- для циклических команд, повышенной точности и sal , shl флаг OF = 1, если после сдвига старший бит изменился;

- после sar OF = 0;

- после shr OF = значению старшего бита исходного числа.

Дополнительные команды:

- BT <приемник>, <источник>

- BTS <приемник>, <источник>

- BTR <приемник>, <источник>

- BTC <приемник>, <источник>

- BSF <приемник>, <источник>

- BSR <приемник>, <источник>

 

Структуры:

Структуры – это сложный тип данных, объединяющий в себе данные различных типов и различной длины. Структура состоит из полей-данных различного типа и длины, занимая последовательные байты памяти. Чтобы использовать переменные типа структура, необходимо вначале описать идентификатор типа структуры, а затем описать переменные такого типа. Описание типа структуры:

<имя типа>struc

<описание поля>

------------------------

<описание поля>

<имя типа>ends

<имя типа> - это идентификатор типа структуры,

struc и ends - директивы,

причем <имя типа > в директиве endsобязательно потому, что endsзакрывает сегмент.

Для описания полей используются директивы определения DB, DW, DD и т.д.

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

Например:

TDatastruc ; TData – идентификатор типа

yDW 2000 ; y, m, d – имена полей. Значения, указанные

mDB ? ; в поле операндов директив DW и DB , dDB 28

; называются значениями полей, принятыми

TDataends ; по умолчанию.

? – означает, что значения по умолчанию нет.

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

2б 1б 1б размеры полей в байтах

TData y m d

Нахождение адресов полей +0 +2 +3 смещение относительно началаструктуры.

Описание переменных типа структуры осуществляется с помощью директивы вида:

имя переменной имя типа <нач. значения>

Здесь уголки не метасимволы, а реальные символы языка, внутри которых через запятую указываются начальные значения полей.

Начальным значением может быть: 1) ? 2) выражение 3) строка 4) пусто.

Например:

y m d

dt1 TData<?, 6, 4> ? 6 4

dt2 TData<1999, , > 1999 ? 28

dt3 TData< , , > 2000 ? 28

Идентификатор типа TData используется как директива для описания переменных также, как используются стандартные директивы DB, DW и т.д.

Если начальные значения не будут умещаться в отведенное ему при описании типа поле, то будет фиксироваться ошибка.

Правила использования начальных значений и значений по умолчанию:

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

2) если в поле переменной указан знак?, то это поле не имеет начального значения, даже если это поле имеет значение по умолчанию (поле y переменной dt1);

3) Если в поле переменной указано выражение или строка, то значение этого выражения или сама строка становится начальным значением этого поля (поля m и d переменной dt1 и поле y переменной dt2);

4) Если начальное значение поля переменной «пусто» - ничего не указано при описании переменной, то в качестве начального устанавливается значение по умолчанию – значение, указанное при описании типа, если же в этом поле при описании типа стоит знак?, то данное поле не имеет никакого начального значения (поля m переменных dt2 и dt3).

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

6) Отсутствие начального значения отмечается запятой.

7) Если отсутствуют начальные значения нескольких последних полей, то запятые можно не ставить. Если отсутствуют значения первого поля или полей, расположенных в середине списка полей, то запятые опускать нельзя. Например:

dt4 TData<1980, ,> можно dt4 TData<1980>

dt5 TData<, , 5> нельзя заменить на dt5 TData< 5 >.

8) Если отсутствуют все начальные значения, опускаются все запятые, но угловые скобки сохраняются:

dt6 TData<>

9) При описании переменных, каждая переменная описывается отдельной переменной, но можно описать массив структур, для этого в директиве описания переменной указывается несколько операндов и (или) конструкция повторения DUP. Например:

dstTData<, 4, 1>, 25 DUP (<>)

Описан массив из 26 элементов типа TData, и первый элемент (первая структура) будет иметь начальные значения 2000, 4, 1, а все остальные 25 в качестве начальных будут иметь значения, принятые по умолчанию: 2000, ?, 28.

Имя первой структуры dst, второй – dst+4, третьей – dst+8 и т.д.

10) Работать с полями структуры можно также, как с полями переменной комбинированного типа в языках высокого уровня:

<имя переменной > .< имя поля>

Например, dt1.y, dt2.m, dt3.d

В отличие от языков высокого уровня Ассемблер приписывает имени типа и имени переменной размер (тип), равный количеству байтов, занимаемых структурой:

typeTData = typedt1 = 4

И это можно использовать при программировании, например, так:

; выполнить побайтовую пересылку dt1 в dt2

movCX, typeTData; количество повторений в CX

mov SI, 0 ; i = 0

m: movAL, byteptrdt1[SI]; побайтовая пересылка

mov byte ptr dt2[SI], AL; dt1 в dt2

incSI; i = i+1

loopm; использование byteptrобязательно

-----------------------------------

11) Точка, указанная при обращении к полю, это оператор Ассемблера, который вычисляет адрес по формуле:

<адресное выражение> +<смещение поля в структуре>

Тип полученного адреса совпадает с типом поля, т.е.

type (dt1.m) = type m = byte

Адресное выражение может быть любой сложности, например:

1) movAX, (dts+8).yтретий элемент массива у поля у

2) mov SI, 8

inc (dts[SI]).m ; Aисп= (dst + [SI]). m = (dst + 8).mсмещение по m внутри структуры

3) lea BX, dt1

mov [BX].d, 10 ; Aисп = [BX] + d = dt1.d

Замечания:

- type (dts[SI]).m = type (dts[SI].m) = 1, но type dst[SI].m = type dst = 4

- Если при описании типа структуры в директиве, описывающей некоторое поле, содержится несколько операндов или конструкция повторения, то при описании переменной этого типа данное поле не может иметь начального значения и не может быть определено знаком ?, это поле должно быть пустым.

Одно исключение:

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

Например:student struc

f DB 10 DUP (?); фамилия

i DB “ ******* “; имя

gr DW ?; группа

oz DB 5, 5, 5; оценки

Studentends

Описание переменных:

st1 student<“Petrov”, >; нельзя, т.к. поле f не строка

st2 student< , “Petr”, 112, > ;можно, f – не имеет начальногозначения

st3 student< , “Aleksandra” >; нельзя, в i 10 символов, а допустимо не больше 7

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

1) ;prim1.asm – прямое обращение к полям структуры

Modeltiny

Code

org 100h; обход 256 байтного префикса пр-го сегмента – PSP…

Start: mov AH, 9



2018-07-06 690 Обсуждений (0)
Assume cs: cseg, ds:dseg, ss:sseg 0.00 из 5.00 0 оценок









Обсуждение в статье: Assume cs: cseg, ds:dseg, ss:sseg

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Почему человек чувствует себя несчастным?: Для начала определим, что такое несчастье. Несчастьем мы будем считать психологическое состояние...
Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (690)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.009 сек.)