Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
loktuhin_arhitektura_kompjutera_kniga_2.pdf
Скачиваний:
89
Добавлен:
13.04.2015
Размер:
704 Кб
Скачать
☆

Операциию вывода текста на экран можно также представить в виде макроопределения VDISP MACRO.

vdisp macro

 

push

ax

mov

ah,9 ;Функция DOS

int 21h

;вывода строки на экран

pop ax

 

endm

 

Приведенная последовательность команда вызывается из программы макрокомандой VDISP (вместо CALL VDISP). Исходный тест макроопределения приводится в начале программы.

3.8. Программирование обработки цепочек данных

Цепочечные команды

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

В МП 80х86 имеется пять базовых однобайтовых цепочечных ко- манд-примитивов, предназначенных для обработки одного элемента цепочки. Если элементом является байт, то в мнемонике команд указывается буква B, если слово, то – W, например: MOVSB и MOVSW. В общем случае при обработке строк данных:

–цепочка-приемник находится в дополнительном сегменте данных (ES) и ее элемент адресуется регистром DI,

–цепочка-источник находится в сегменте данных (DS) и ее элемент адресуется регистром SI.

Задание начальных адресов цепочек, например приемника

STRING1 и источника STRING2, производится командами LEA DI,ES:STRING1 и LEA SI,STRING2. Однако обе цепочки можно разместить в сегменте данных, если перед их обработкой сделать равными значения сегментных регистров ES и DS.

В зависимости от состояния признака направления DF регистра F после каждой операции над элементом цепочки выполняется инкремент (DF = 0) или декремент (DF = 1) указателей DI и SI (при обработке байт

– на единицу, при обработке слов – на два).

Цепочечной команде может предшествовать специальный префикс повторения REP, который заставит МП повторить команду и модифицировать CX ← CX + 1. Операции повторяются, пока CX ≠ 0. Перед командами сравнения CMPS и SCAS мнемоника префикса имеет

76

вид REPZ/REPE или REPNZ/REPNE. Для REPZ примитив повторяется, пока CX ≠ 0 или признак ZF = 1, а для REPNZ – пока CX ≠ 0 или ZF = 0.

Программы, приведенные в примерах 3.13 и 3.14, выполняют одно и то же действие – сравнивают строки пока не будут просмотрены 100 элементов или пока не встретятся совпадающие элементы.

Пример 3.13

;Найти совпадения

mm1: cmpsb

;Сравнить [SI] – [DI], SI ← SI + 1, DI ← DI + 1

dec

cx

; CX ← CX – 1

jnz

mm1

;Повторять, пока CX ≠ 0 или FZ = 0

 

Пример 3.14

 

 

;Найти совпадения.

repnz

cmpsb

;Те же операции, что и в примере 3.13.

Используя в примере 3.13 вместо JNZ другие команды условного перехода, можно сравнивать элементы и по другим признакам, например по признаку «больше» или «меньше».

Далее, в примере 3.15, показана процедура копирования 10 элементов из строки STRING2 в строку STRING1.

Пример 3.15

;Копирование элементов строки

;Пусть цепочки находятся в сегменте данных string2 db ‘Петрова Н., Иванов А.’ ;Цепочка-источник

string1 db 20 dup(?)

;Цепочка-приемник

;Процедура копирования

copir proс

 

 

push

ds

;Заставить указывать es

pop

es

;на сегмент данных

cld

 

;Сброс для обработки слева направо

lea

si,string2

;Адрес строки STRING2 в SI

lea

di,string1

;Адрес строки STRING1 в DI

mov

cx,20

;Число элементов в CX

rep movsb

;Скопировать байты

ret

 

 

copir endp

 

 

Ввод строковых данных в ПК

77

В программе значения элементов в строке можно задать с помощью директивы DB или DW.

При вводе строки с клавиатуры целесообразно пользоваться функцией DOS 0AH, вызываемой командой INT 21H. Чтобы воспользоваться ею, необходимо зарезервировать в сегменте данных место для строки. Например, оператор

string db 64,65 dup(?)

резервирует место для строки STRING, содержащей 64 элемента. Чтение строки с клавиатуры в память без изображения на экране

производится командами, приведенными в примере 3.16.

Пример 3.16

;Чтение строки с клавиатуры

lea

dx,string

;Сделать DX указателем буфера

mov

ah,0ah

;Прочитать строку,

int

21h

;ввод завершить нажатием [Enter]

После их выполнения в первом байте буфера STRING находится длина буфера 64, а во втором – число фактически введенных символов. Элементы строки STRING+2 размещаются с третьего байта.

Порядок программирования и отладки программ обработки цепочек

1.Изучите форматы цепочечных команд и примеры программ обработки строк (пп. 3.8.1, 3.8.2).

2.Разработайте для заданного варианта программу обработки строк (см. приложение 5). Для более наглядного выполнения программы используйте процедуры ввода и изображения строк, приведенные в примере 3.16.

3.С помощью системных программ (см. п. 3.5) сформируйте исходный, объектный и исполняемый модули.

4.Выполните программу в отладчике TD.

5.Выполните программу.

3.9.Встроенное ассемблирование

Вобщем случае при разработке пользовательских программ используют принципы встроенного ассемблирования и вызовы функций на языке ассемблера из языка высокого уровня (ЯВУ).

78

Их организация дается на примере взаимодействия ЯВУ «ТурбоСи» с «Турбо-ассемблером».

Встроенное ассемблирование на Турбо-Си

Язык программирования Турбо-Си имеет в своем составе встроенный ассемблер. Это позволяет включать в программу на Си отдельные команды языка ассемблера. При этом включаемая команда должна начинаться с директивы Си – asm.

Пример программы на Си со встроенным ассемблированием:

int i;

 

 

. . .

 

 

i=0;

/*установка i = 0 на СИ*/

asm dec word ptr i;

/*i = i – 1

на ассемблере*/

i++;

/*i = i + 1

на Си*/

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

mov

word ptr

[bp-02],0000

dec

word ptr

[bp-02]

inc

word ptr

[bp-02]

При трансляции Си-программ со встроенным ассемблером необходимо применять только спецкомпилятор tсс.ехе, который поддерживает средства встроенного ассемблера.

Ограничения на встроенное ассемблирование

1. Командами перехода встроенного ассемблера можно ссылаться только на метки Си. Типичная ошибка:

asm JZ MM1; asm DEC CX;

asm MM1: ADD AX,10; Правильно:

asm JZ MM1;

. . .

MM1: x = x+a;

2. Команды встроенного ассемблера, за исключением команд перехода, могут иметь любые операнды, кроме меток Си.

79

3. Необходимо сохранять регистры BP, SP, CS, DS, SS в командах встроенного ассемблера перед командами, использующими эти регистры.

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

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

Вызов функции на языке ассемблера из Си

Для организации вызовов отдельно формируются основной модуль на Си и модуль на ассемблере как вызываемая функция. Исполняемый ехе-файл создается программой tcc путем объединения двух исходных файлов:

tcc < имя файла на Си>.c < имя файла на ассемблере>.asm

При компоновке необходимо соблюдать соглашения об именах переменных и меток, передаваемых от одного модуля к другому. Это делается с помощью директив PUBLIС и EXTRN в модуле на ассемблере и директивы extern в модуле на Си. Кроме того, должны быть соблюдены одинаковые типы моделей памяти в Си и ассемблере. Это достигается с помощью упрощенных сегментных директив.

Имена общих переменных в модуле на asm должны начинаться со знака подчеркивания: _х, _summa и т.д.

В примере 3.15 приведена программа на Си и ассемблере. Программа на Си вызывает с помощью функции summa() процедуру, которая реализована на ассемблере и производит расчет выражения Z = X + Y, где X, Y, Z – переменные, представленные в виде 16-ричных чисел. Процедура _summa позволяет складывать только двоичные числа в формате слова, поэтому в Си с помощью оператора scanf их вводят в

16-ричной системе счисления.

Пример 3.15

Программа на Си и ассемблере

/* Программа на Си (основной модуль) */ #include<stdio.h>

extern int summa(); /* переменная summa определена */

80

/* в другом модуле */

int X,Y; /* переменные X, Y доступны другим модулям */ extern int z; /* переменная z определена в другом модуле */ main ()

{

printf (“\n Введите целое 16-ричное число Х = ”); scanf (“%X, &X”);

printf (“\n Введите целое 16-ричное число Y = ”); scanf (“%X, &Y”);

summa(); /* вызов процедуры _summa из asm-модуля */ printf (“\n Сумма Z = X + Y = % X, Z”);

}

;Процедура на ассемблере, реализующая операцию Z = X + Y

.MODEL

small

.DATA

 

_y:word ;Эти переменные определены

extrn

_x:word,

 

 

 

;в модуле на Си

public

_z

 

;Переменная z доступна другим

 

 

 

; модулям

_z

dw 0

;Переменная z определена в asm-модуле

 

.CODE

;Является глобальной

public

_summa

_summa

proc

;Процедура _summa

 

 

mov

ax,_x

 

 

add

ax,_y

 

 

mov

_z,ax

 

 

ret

 

_summa

endp

 

 

 

end

 

Между типами данных в Си и ассемблере существует следующее соответствие:

Типы данных в Си

Типы данных

в ассемблере

 

сhar

byte (db)

int

word (dw)

и т.д.

 

Тип переменной z можно определить в модуле на Си директивой int z. Тогда в asm-модуле отсутствовала бы строка:

81

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]