Лекции по Вычислительным машинам, системам и сетям   

5. Программирование на языке Ассемблер

5.7. Выделение памяти под переменные и массивы

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

perem db 73.

Мы задали переменную, назвав ее именем perem, попросили транслятор выделить для этой переменной байт памяти (директива db) и загрузить в этот байт число 73. Исходное значение переменной – 73, по ходу работы программы это значение может меняться. Кроме директивы db (defined byte) есть еще директивы dw (defined word) (выделить в памяти слово), dd (defined double word) (выделить двойное слово) и другие. Например:

cursor db 12

x1 dw  542h

counter dd  37*14.

Переменные заданы и работать с ними несложно:

mov ax, x1      ;записываем в ах значение переменной х1

add cursor, 2       ;прибавляем двойку к значению ;переменной cursor

mov bl, byte ptr counter+3        ;записываем в bl значение ;старшего (третьего) байта ;переменной counter.

Последняя команда требует развернутого комментария. Переменная counter описана как двойное слово (4 байта), а регистр bl имеет формат 1 байт. Для того чтобы транслятор не выдавал предупреждения о «несогласованности типов операндов», а понял, что программист знает, чего он хочет, вставлена директива byte ptr. Если в команде было написано не counter + 3, а counter, то обратились бы не к третьему, а к нулевому (младшему) байту двойного слова.

Совершенно аналогично задаются массивы:

note db 40, 35, 27, 90   ;задали массив из четырех чисел.

Обратиться, например, ко второму элементу нашего массива (число 27) можно одним из следующих способов:

mov dh, note+2

или

mov si, offset note       ;после этого в si смещение ;нулевого элемента массива

mov dh, [si+2]

или

mov si, offset note

add si, 2          ;теперь в si смещение второго элемента ;массива

mov dh, [si].

Недостаток (или достоинство?) последнего варианта в том, что мы портим si и транслятор указывает не на начало массива. Отметим также, что +2 во всех трех вариантах означает «смещение на два байта относительно начала массива» и далеко не всегда является смещением второго элемента массива. Так, например, если задан массив слов:

sl dw 707, 12, 421, 0, 1234,

то для того чтобы обратиться к его второму элементу (число 421), надо написать, допустим, так:

mov ax, sl+4        ;начало массива плюс 4 байта.

Можно задавать и символьные массивы. Например:

strochka db ‘Это строка символов’.

Транслятор сам переведет все символы, записанные между апострофами, в их ASCII-коды и получим массив из 19 байт (17 букв и 2 пробела). Иногда нужно задать большой массив, например, состоящий из 1000 элементов, причем исходное состояние элементов не важно и всем элементам можно присвоить значение 0 (или 117, или 66, …). Такая ситуация возникает, когда надо создать в памяти буфер, в который затем будет записываться информация из какого-то файла. Не писать же тысячу нулей через запятую. На этот случай имеется директива dup (повторять):

mass dw  1000 dup (117)       ;то что повторяется задается ;в скобках.

Можно создавать и более сложные конструкции:

out_string db ‘nomber of files  = ’, 4 dup (?), 10,13,’$’.

Это заготовка некой строки для вывода на экран. 4 dup (?) – выделяет 4 байта, в которые программа запишет ASCII-коды цифр, из которых состоит найденное «число файлов» (вместо ? можно было написать 0, результат был бы тем же). 10 и 13 – управляющие коды, переводящие курсор в начало новой строки экрана. ‘$’ – означает конец выводимой строки. В заключение приведем пример массива, при задании которого часто встречаются ошибки:

pause db 11, 22, 33, 44, 55, 66, 77, 88

db 99, 100, 32, 0.

Если продолжаем массив на новой строчке, то надо начать эту строчку с директивы (db), а на предыдущей строчке после последнего элемента запятая не ставится!



*****
Новосибирск © 2009-2017 Банк лекций siblec.ru
Лекции для преподавателей и студентов. Формальные, технические, естественные, общественные, гуманитарные, и другие науки.