Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Основы программирования на Ассемблере. Учебное пособие.pdf
Скачиваний:
0
Добавлен:
11.08.2026
Размер:
607 Кб
Скачать

Сортировка вставками

Метод основан на внедрении в отсортированную часть массива элемента, следующего за этой частью, если он удовлетворяет условию сортировки. На первом шаге сортировки 2- й элемент сравнивается с 1-м. На 2-м шаге 3-й элемент сравнивается с двумя первыми. Среди уже отсортированных i – 1 элементов массива вставляют i-й элемент без нарушения порядка, т. е. при вставке i-го элемента на j-е место (i > j) элементы с индексами от j до i увеличивают свой номер на 1.

for i: = 2 to N do begin // цикл по числу шагов

b:= x[i]; //значение элемента за отсортированной частью

j:= 1;

while b>x[[j] do j: = j+1; //определение номераj для вставки элемента for k: = I downto j+1 do x[k]: = x[k-1]; //увеличениеиндексов элементов

x[j]: = b; //вставка значения b на место j-го элемента

end;

Пример сортировки массива А из N элементов по убыванию мето-

дом пузырька

 

MOV CX,N

;установить счетчик

 

DEC CX

;на N-1

LOOP1:

MOV DI,CX

;счетчик в DI

 

MOV BX,0

;сбросить ВХ

LOOP2:

MOV AX,A[BX]

;в АХ загрузить i элемент массива

 

CMP AX,A[BX+2]

;и сравнить его с i+1 элементом

 

JGE CONT

;если A[i]<A[i+1], то

 

XCHG AX,A[BX+2]

;обменять

 

MOV A[BX],AX

;и запомнить большее число

CONT:

ADD BX,2

;увеличить индекс

 

LOOP LOOP2

;если не конец прохода, повторить

 

MOV CX,DI

;восстановить счетчик внешнего цикла

 

LOOP LOOP1

;если не последний проход, повторить

79

18.КОМАНДЫ СДВИГА

ИЦИКЛИЧЕСКОГО СДВИГА

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

обрабатывают байт или слово;

имеют доступ к регистру или к памяти;

сдвигают влево или вправо;

сдвигают на величину до 8 бит (для байта) и 16 бит (для слова);

сдвигают логически (без знака) или арифметически (со знаком). Значение сдвига на единицу может быть закодировано как непо-

средcтвенный операнд, значение больше единицы должно находиться в регистре CL.

При выполнении команд сдвига флаг CF всегда содержит значение последнего выдвинутого бита. Существуют следующие команды сдвига:

SHR ;Логический (беззнаковый) сдвиг вправо

SHL ;Логический (беззнаковый) сдвиг влево SAR ;Арифметический сдвиг вправо

SAL ;Арифметический сдвиг влево

Пример выполнение команды SHR:

MOV CL,03

; AX:

MOV AX,10110111B ; 10110111

SHR AX,1

; 01011011 ;Сдвиг вправо на 1

SHR AX,CL

; 00001011 ;Сдвиг вправо на 3

Первая команда SHR сдвигает содержимое регистра AX вправо на один бит. Выдвинутый в результате один бит попадает в флаг CF, а самый левый бит регистра AX заполняется нулем.

Вторая команда сдвигает содержимое регистра AX еще на три бита. При этом флаг CF последовательно принимает значения 1, 1, 0, а в три левых бита в регистре AX заносятся нули.

Пример арифметического сдвига вправо SAR:

MOV CL,03

; AX:

 

MOV AX,10110111B ; 10110111

SAR AX,1

; 11011011

;Сдвиг вправо на 1

SAR AX,CL

; 11111011

;Сдвиг вправо на 3

 

 

80

Команда SAR имеет важное отличие от команды SHR: для заполнения левого бита используется знаковый бит. Таким образом, положи-

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

При сдвигах влево правые биты заполняются нулями. Результат команд сдвига SHL и SAL идентичен.

Сдвиг влево часто используется для удваивания чисел, а сдвиг вправо – для деления на 2. Эти операции осуществляются значительно быстрее, чем команды умножения или деления. Деление пополам нечетных чисел (например, 5 или 7) образует меньшие значения (2 или 3 соответственно) и устанавливает флаг CF в единицу. Кроме того, если необходимо выполнить сдвиг на два бита, то использование двух команд сдвига более эффективно, чем использование одной команды с загрузкой регистра CL значением 2.

Для проверки бита, занесенного в флаг CF, используется команда

JC (переход, если есть перенос).

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

ROR ;Циклический сдвиг вправо

ROL ;Циклический сдвиг влево

RCR ;Циклический сдвиг вправо с переносом

RCL ;Циклический сдвиг влево с переносом Пример циклического сдвига ROR:

MOV CL,03

;

BX:

MOV BX,10110111B

; 10110111

ROR BX,1

; 11011011 ;Сдвиг вправо на 1

ROR BX,CL

; 01111011 ;Сдвиг вправо на 3

Первая команда ROR при выполнении циклического сдвига переносит правый единичный бит регистра BX в освободившуюся левую позицию. Вторая команда ROR переносит таким образом три правых бита.

В командах RCR и RCL в сдвиге участвует флаг CF. Выдвигаемый из регистра бит заносится в флаг CF, а значение CF при этом поступает в освободившуюся позицию.

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

81

дится в регистрах DX:AX так, что левые 16 бит лежат в регистре DX, а правые – в AX. Для умножения на два этого значения возможны следующие две команды:

SHL AX,1

; Умножение пары регистров

RCL DX,1

; DX:AX на 2

Здесь команда SHL сдвигает все биты регистра AX влево, причем самый левый бит попадает в флаг CF. Затем команда RCL сдвигает все биты регистра DX влево и в освободившийся правый бит заносит значение из флага CF.

19. МАКРОСРЕДСТВА

Для каждой закодированной команды Ассемблер генерирует одну команду на машинном языке. Для каждого закодированного оператора компиляторного языка Pascal или C генерируется один или более (чаще много) команд машинного языка. Можно считать, что компиляторный язык состоит из макрооператоров.

Ассемблер MASM также имеет макросредства, но макросы здесь определяются программистом. Для этого задается имя макроса, директива MACRO, различные Ассемблерные команды, которые должен генерировать данный макрос и для завершения макроопределения – директива MEND. Затем в любом месте программы, где необходимо выполнение определенных в макрокоманде команд, достаточно закодировать имя макроса. В результате Ассемблер сгенерирует необходимые команды [6, 7, 9].

Использование макрокоманд позволяет:

упростить и сократить исходный текст программы;

сделать программу более понятной;

уменьшить число возможных ошибок кодирования. Макроопределение должно находиться до определения сегмента. Пример простого макроопределения по имени INIT1, которое ини-

циализирует сегментные регистры для EXE-программы:

INIT1 MACRO

ASSUME CS:CSEG,DS:DSEG,SS:STACK;ES:DSEG PUSH DS

SUB AX,AX PUSH AX

82

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