Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
74
Добавлен:
11.02.2014
Размер:
272.07 Кб
Скачать

Программирование типовых управляющих структур

Условный оператор if-else

Условный оператор if-else используется для принятия решения о дальнейшем пути исполнения программы. Синтаксис условного оператора в нотации языка Pascal:

if выражение then оператор1;

else

оператор2

Алгоритм работы условного оператора – вычисляется логическое значение выражения: если оно истинно, то выполняется оператор1, в противном случае – оператор2.

На ассемблере данные варианты условного оператора можно реализовать следующим образом:

; полный вариант оператора if выражение then оператор1 else оператор2

cmp op1,op2

; вычисление выражения

jne else1

 

; …

; последовательность команд, соответствующая оператор1

jmp endif

 

else1:

 

;…

; последовательность команд, соответствующая оператор2

endif:

; конец полного условного оператора

; …

 

Вместо команды СМР можно использовать любую команду, изменяющую флаг, который будет анализироваться последующим оператором условного перехода. Аналогично и с командой JNE, вместо которой может стоять требуемая в данном вычислительном контексте команда условного перехода.

Оператор выбора case

Оператор case (переключатель) в программе на ассемблере можно реализовать несколькими способами: использованием команд сравнения и с использованием таблицы. В нотации языка Pascal синтаксис оператора case выглядит так:

case константное_значение_«выражение» of константное выражение_1: операнд1; константное выражение_2: операнд2;

константное выражение_n: операндN

else

операнд_default;

end;

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

1,2,3 («выражение»):

; …

; формирование константное_значение_«выражение

11

mov al,константное_значение_«выражение»

cmp al,1

; проверка первой альтернативы (константное выражение_1=1?)

jе handle_condition1 ; равно, идем на обработку

cmp al,2

; проверка второй альтернативы (константное выражение_2=2?)

je handle_condition2 ; равно, идем на обработку

cmp al,3

; проверка третьей альтернативы (константное выражение_3=3?)

je handle_condition2 ; равно, идем на обработку

; если condition <> 1,2,3 , то производим обработку по умолчанию

;…

; последовательность команд для обработки по умолчанию

jmp end_switch

; уходим на конец switch

handle_conditionl:

 

; …

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

jmp end_switch

; уходим на конец switch

handle_condition2:

 

; …

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

jmp end_switch

; уходим на конец switch

handle_condition3:

 

; …

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

end_switch:

 

;…

; продолжение программы

Второй (табличный) способ. Для реализации рассматриваемого способа в памяти моделируется некоторое подобие таблицы. Каждая строка таблицы состоит из двух ячеек. Строки таблицы располагаются в памяти последовательно – друг за другом. В первой ячейке таблицы располагается значение константное_выражение_n, во второй ячейке – адрес перехода, если выполняется условие константное_значение_«выражение» = константное_выражение_n. Целью адреса перехода может быть процедура или метка, соответствующая фрагменту кода, обрабатывающему выполнение условия, заданного в заголовке оператора выбора. Реализация табличным способом будет выглядеть так:

.data

table_switch

db 1

 

dw handle_conditionl

 

db 2

 

dw handle_condition2

 

db 3

 

dw handle conditions

;

.code

;… формирование константное_значение_«выражение» mov al,константное_значение_«выражение»

mov bx,offset table_switch

mov cx,3

; счетчик циклов = количество альтернатив

next_condition:

 

cmp al,[bx]

; проверка очередной альтернативы

jne next

; к следующему элементу

jmp word ptr [bx+1]

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

next:

 

add bx,3

; адрес следующей строки таблицы > bx

loop next_condition

 

;default:

;если condition<>1,2,3, то производим обработку по умолчанию

12

; …

; последовательность команд для обработки по умолчанию

jmp …

; уходим, куда нужно

handle_condition1:

 

; …

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

jmp …

; уходим, куда нужно

handle_condition2:

 

; …

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

Jmp …

; уходим, куда нужно

handle_condition3:

 

; …

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

jmp …

; уходим, куда нужно

; …

; продолжение программы

Оператор цикла с предусловием while

Оператор цикла с предусловием while имеет следующий формат: while выражение условие do

тело цикла

На ассемблере это может выглядеть так:

while_begin:

 

cmp al,1

; вычисление логического значения «выражение условие»

jne end_while

; ЕСЛИ не равно ТО ПЕРЕЙТИ НА end_while

; …

; что то делаем – тело цикла

jmp while_begin

; переход на начало очередной итерации цикла

end_while:

; конец цикла

; …

; продолжение программы

Операторы continue и break

Прекращение выполнения цикла возможно в двух случаях: значение выражениеусловие равно FALSE или имеет место безусловная передача управления за пределы.

Алгоритм выполнения операторов break, goto и continue прост, они передают управление в определенную точку программы:

break: сразу за конец цикла;

goto: в произвольное место программы;

continue: на начало последнего открытого оператора while, do или for.

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

Оператор цикла с постусловием do-while

Его формат: repeat

тело цикла

until (выражение условие)

Псевдокод на ассемблере реализации этого оператора выглядит так:

do_while_begin:

 

; …

; операторы цикла

13

; вычисление логического значения «выражение условие» ЕСЛИ «выражение условие» = FALSE ТО ПЕРЕЙТИ НА end_while

ПЕРЕЙТИ на do_while_begin: ; переход на начало очередной итерации цикла

end_while:

;

конец цикла

;…

;

продолжение программы

Оператор итерационного цикла for

Формат:

for инициализация_счетчика to выражение do тело цикла

Ассемблер с помощью команды LOOP поддерживает только один вариант организации такого цикла. Реализацию произвольного варианта цикла for можно с помощью следующего псевдокода:

;инициализация переменной цикла for_begin:

;вычисление логического значения «выражение условие» ЕСЛИ «выражение условие» = FALSE ТО ПЕРЕЙТИ НА end_for

; …

; операторы

цикла

; …

; вычисляем

выражение – очередное значение переменной цикла

ПЕРЕЙТИ на for_begin:

; переход на начало очередной итерации цикла

end_for:

 

; конец цикла

; …

 

; продолжение программы

В качестве примера рассмотрим программу, суммирующую или вычесляющую разность в зависимости от выбора пользователя и выводящую результат на экран в виде строкового представления (листинг 6).

Листинг 6 – Комплексный пример

.model small

 

 

.stack 100h

 

 

.data

 

 

A dw 7934

; 1EFEh

B dw 2471

; 9A7h

tbl db 31h

; условие перехода

dw sum

; адрес метки для перехода

db 32h

 

dw subt

szSelect db 'a = 7934',10,13,'b = 2471',10,13,'1 operation "+"; 2 operation " ": ','$'

szResult db 10,13,'Result = '

 

Result

db '00000','$'

; символьная строка для результата

.code

 

 

mov ax,@data

 

mov ds,ax

 

 

mov es,ax

 

 

mov ah,9

 

 

lea dx,szSelect

 

int 21h

; вывод приглашения

mov ah,1

; функция ввода

int 21h

 

 

14

mov bx, offset tbl

; загрузка таблицы переключателей

mov cx,2

 

; число альтернатив

next_condition:

 

 

cmp al,[bx]

; проверка аьтернативы

jne next

 

; альтернатива не подходит

jmp word ptr [bx+1]

; переход на метку с адресом обработчика

next:

 

 

add bx,3

 

; адрес следующей строки (альтернатива)

loop next_condition

 

sum:

; переход если выбран пункт "+" (сумма)

mov ax,A

; ax = 7934

add ax,B

; ax = 7934 + 2471 = 10405d = 28A5h

jmp exit_switch

 

subt:

; переход если выбран пункт " " (разность)

mov ax,A

; ax = 7934

sub ax,B

; ax = 7934 2471 = 5463d = 1557h

exit_switch:

; выход из переключателя

lea si,Result+4 ; адрес конца строки результата

call IntStr ; функция перевода числа из 2 ного представления в строку

 

; параметры: ax число, si адрес строки

mov ah,9

; вывод результата в виде строки

lea dx,szResult int 21h

mov ah,1 int 21h

mov ax, 4C00h int 21h

IntStr proc mov cx,10

next_digit:

cmp ax,0010 jb exit xor dx,dx div cx

or dl,30h mov [si],dl dec si

jmp next_digit

exit:

or al,30h mov [si],al

ret

IntStr endp end

15

Задания

1 X DB 206

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

а) cmp x,210

б) cmp x,210

в) cmp x, 40

г) cmp x, 40

д) cmp x,216

ja met

je lab

jg met

jl met

jl met

2 X DW ? ; число со знаком

Определить, какой из следующих фрагментов правильно реализует оператор if X>80 then

X:=X 1

else

X:=X+1

а) cmp x,80

б) cmp x,80

в) cmp

x,80

г) cmp

x,80

jle m

jg m

jle

m

jng

m

dec x

dec x

dec

x

dec

x

m: inc x

jmp l

jmp

l

jmp

l

 

m: inc x

m: inc x

m: inc x

 

l:

l:

 

l:

 

3 Пусть A, B и C – знаковые переменные-слова. Записать в регистр DL значение 3, 2, 1 или 0 в зависимости от того, может ли существовать треугольник с такими длинами сторон (и если да, то какого он вида – равносторонний (3), равнобедренный (2) или какой-то иной (1)) или не может (0). Условие существования треугольника: сумма длин двух сторон должна быть больше третей стороны.

4 N DB ? ; N≥1

F DW ?

Записать в F:

а) N-е число Фибоначчи (FN);

б) первое из чисел Фибоначчи, превосходящих 10000. (Определение чисел Фибоначчи Fk: F0=F1=1, Fk=Fk-1+Fk-2.)

5 Напечатать таблицу умножения (в десятичной системе счисления) для числа N (номер по журналу). Пример для числа 9:

 

1

2

3

4

5

6

7

8

9

9

9

18

27

36

45

54

63

72

81

16