Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КПиЯП(Шпоры).doc
Скачиваний:
18
Добавлен:
11.05.2015
Размер:
294.4 Кб
Скачать

18. Структура резидентной программы. См пред.Пункт.

Резидентные программы.

Программы, кот. ост. в памяти после возврата действия в ДОС носят назв. резидентных. Блоки памяти в которых сидят резиденты ОС отмечает как занятые. Прерывания делятся: 1) Аппаратные: - маскируемые; - немаскируемые; 2) Программные: - прерывания BIOS; - прерывания DOS; пользовательские; 3) Исключительные ситуации: - ошибки; - ловушки; - аварийное завершение. Они вызываются процессором при возникновении ошибки(00 h – 1Fh) и поддерживаются только в защищенном режиме. Сущ. 2 способа оставить программу резидентной: 1) с помощью int 21h (ah=31h; al=код возврата; dx=размер резидента в 16-байтных параграфах включая PSP; cs=сегмент резидента). 2) int 27h – оставить программу резидентной(dx= адрес последнего байта программы; cs = сегмент резидента). 1-ый исп. когда резиденты большого размера и явл. exe. Резиденты небольшого размера, реализуются в виде com и ост. в памяти обработчиком int 27h. Резиденты – активные (перехватывают прерывания от внешних устройств) и пассивные (активизируются при вып. команды int с нужным номером). Способы установки векторов прерывания: 1) непосредственным обращением к соотв. байтам( xor ax,ax---mov es,ax---mov ax,es:[9*4]---mov int_ofs,ax---mov ax,es:[9*4+2]---mov int_seg,ax---Установить адрес входа в собственный обработчик также можно напрямую, путем модификации таблицы векторов(запрещает прерывание т.к. недопустимо чтобы INT_NUM появилось в момент, когда изменяем вектор.--- push 0---pop es---mov bx,INT_NUM---shl bx,2---mov ax,seg ISR---shl eax,16---mov ax,offset ISR---mov es:[bx],eax---sti). В многозадачной среде ОС может поддерживать несколько таблиц векторов прерываний, и реальный физический адрес может быть известен только DOS. 2) Используя функции DOS. Функция 35h получает адрес обработчика.(Вход ah=35h,al=номер прерывания; выход es:bx=адрес обработчика). 25h – устанавливает адрес входа в обработчик.(вход ah=25h; al=номер прерывания; ds:dx = адрес нового обработчика; выход – ничего).

19. Интерфейс модулей, написанных на языке ассемблера с модулями, написанными на языке с.

Команды ассемблера в тексте программы на C без изменения вкл. в формируемый компилятором код. Для встроенного ассемблера разр. использовать: - машинные команды; строковые команды; - все инструкции передач управления с прямой или косвенной адресацией; - директивы описания и определения данных. Нельзя исп. директивы, управляющие его работой: ASSUME,SEGMENT,ENDS,PROC,ENDP,ORG и т.д. а также имя группы DGROUP, имена сегментов _TEXT,_STACK,_DATA и т.п. Можно ссылаться на описанные в С переменные. Группа инструкций, заключенная в фигурные скобки, не требует повторения перед каждой из них ключевого слова “asm”.

#include <iostream.h>

#progme inline

asm v1 dw 10

asm v2 dw 90

void main(void)

{unsigned i;

again:

asm {mov ax,v2

add ax,v1

push ax

mov i,ax

}

printf(“i=%d”,i);

if(i>190)

asm jmp _end_

else if (i==150)

asm {

mov ah,2

mov dl,7

int 21h

}

asm {

pop ax

mov v2,ax

jmp again

}

_end_:

puts(“конец проги”);

}

20. Вызов из программы, написанной на языке С , процедур, написанных на ассемблере.

Общая схема: 1) Процедуры на asm и C объединяются совместно, используя файл-проект. В этом случае перечисляются C функции и имена объектных модулей, написанных на asm после трансляции их с помощью TASM. 2) Компиляция из командной строки: а) выполнить трансляцию модуля на С; б) выполнить трансляцию модуля на ассемблере; в) выполнить объединение объектных модулей. ASM процедура должна удовлетворять ниже перечисленным требованиям: - гарантировать получение необходимой информации редактором связей; - обеспечить получ. значений аргументов, переданных ей при вызове, и видимость всех внешних переменных; - должно собл. соотв. моделей памяти, используемых при компиляции C-функции и при обработке asm процедур. В этой связи ассемблерная процедура должна: а) использовать правило именования сегментов, принятое в С; б) явно описывать все глобальные и внешние идентификаторы; в) поддерживать принятую в С посл. передачи аргументов и возврата значений в точку вызова. Все внешние переменные, на которые ссылается ассемблерная процедура. и описанные в С-функциях как внешние, должны объявляться в asm блоке явно с исп. директивы extrn имя_переменной: тип. Если имеются переменные, описанные в ассемблерном модуле, значения которых исп. в С функции. то они в asm модуле объявляются с атрибутом public.

C_asm.cpp

extern void asm f1(int *i1,int *i2,unsigned long l);

void main (void)

{int i=5,j=7;

unsigned long l=0x12345678;

asm_f1(&I,&j,l);

printf(“i=%d,j=%d,l=%lx/n”,i,j,l); }

Вызов процедуры аsm

.model small .code

public asm_f1

asm_f1 PROC near

push bp

mov bp,sp

push si,di

mov si,[bp+4]

mov di,[bp+6]

mov bx,[bp+8]

mov ax,[bp+10]

mov cx,[si]

xchg cx,[di]

mov [si],cx

pop di si

pop bp

ret

asm_f1 endp

end

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

Для каждой прогаммы нужно указать, какие переменные она передаёт в другой модуль и какие переменные она получает из другого модуля.

Фкнкция С++ должна быть описанна в асм. после дерективы EXTERN.

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

-если она обявлена в асм., то должна иметь атрибут PUBLIC а в С++ - EXTERN

-если она обявлена в С++ как внешняя, тогда в асм. она должна иметь атрибут EXTERN

Если функция на С++ возрващает 16-битное значение(char,short,int,enum) то оно будет помещенов регистр АХ, если 32-битное(long) - то DX:AX причём старшая часть в DX

22. Использование встроенного ассемблера.

Необходимо задать дерективу #pragma inline

Асм. команду записывают в виде asm код_операции операнды (;) или (новая строка)

код_операции - (mov,xor...) Если необходимо задать много асм. команд, то они заключаются в фигурные скобки.

Коментарии ожно записывать только в форме, принятой в языке С++.

21. Транспонирование матрицы заданной в кодовом сегменте.

.model small

.stack 100h

.code

start:

jmp continue ; оставить место для матрицы

razmer equ 4

matrix dw 1,2,3,4

dw 5,6,7,8

dw 9,10,11,12

dw 13,14,15,16

continue:

push cs

pop ds ; направляем ds на сегмент кода

mov si,2 ; si - указывает на matrix[0][1]

mov bx,razmer ; в bx - размер матрицы

shl bx,1 ; bx=bx*2, то есть bx указывает на matrix[1][0]

mov ax,bx ; в ax - смещение, равное длине строки

mov cx,razmer ; в cx - razmer

dec cx ; количество перестановок на 1 меньше, чем размер матрицы

loop1: ; внешний цикл по строкам

push cx ; сохранить cx в стеке

loop2: ; внутренний цикл по столбцам (выше главной диагонали)

mov dx,matrix[bx] ; в dx - элемент ниже диагонали

mov di,matrix[si] ; в di - элемент выше диагонали

mov matrix[bx],di ; переставляем их

mov matrix[si],dx

add si,2 ; смещаемся вправо

add bx,ax ; смещаемся вниз

loop loop2 ; цикл повторяется cx раз

pop cx ; восстанавливаем сохраненное cx

push ax ; сохраняем в стеке длину строки

mov ax,razmer ; вычисляем, на сколько сместиться, чтобы оказаться

sub ax,cx ; главной диагональю

inc ax

shl ax,1

add si,ax ; смещаемся на matrix[i][i+1], i - номер очередного ци

mov bx,si ; уставнавливаем bx на si

pop ax ; восстанавливаем длину строки

add bx,ax ; смещаем bx на строку вниз

sub bx,2 ; и на 1 элемент назад

loop loop1 ; цикл, пока cx != 0

mov ah,4ch

int 21h

end start

22. Ввод символа. Определить его позицию в строке и вывести на экран

.model small

.stack 100h

.data

stroka db 80 dup(?),'$'

symb db ?,' ','$' ; можно и не выделять память для символа

msg_in db 0ah,0dh,"Vvedite simvol:",0ah,0dh,"$"

msg db 0ah,0dh,"Simvol ","$"

msg1 db "nayden! Ego index - ","$"

msg_err db "ne nayden.","$"

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

xor bx,bx ; в bx - индекс вводимого символа

input_loop:

mov ah,01h ; считываем символ

int 21h

cmp al,13 ; если это enter

je for_find ; то конец ввода

mov stroka[bx],al ; иначе записываем символ в строку

cmp bx,80 ; если ввели 80 символов

je for_find ; то конец ввода

inc bx ; увеличиваем bx

jmp input_loop

for_find:

lea dx,msg_in ; вывод msg_in

mov ah,09h

int 21h

mov ah,01h ; ввод нужного символа

int 21h

mov byte ptr symb,al ; сохраняем его в symb ( можно использовать любой из свободных регистров, если хошь)

mov cx,bx ; в cx - длина строки

xor bx,bx ; bx - индекс элемента

mov ah,byte ptr symb ; в ah - нужный символ

find:

cmp ah,stroka[bx] ; сравниваем текущий элемент с нужным симв

je found ; если совпадают, то jmp на found

inc bx ; переход к следующему элементу

loop find ; цикл повторяется cx раз

lea dx,msg ; если символ не найден, то

mov ah,09h ; вывод msg

int 21h

lea dx,symb ; вывод самого символа

int 21h

lea dx,msg_err ; вывод msg_err

int 21h

jmp end_program ; завершить программу

found: ; если найден символ

lea dx,msg ; вывод msg

mov ah,09h

int 21h

lea dx,symb ; вывод самого символа

int 21h

lea dx,msg1 ; вывод msg1

int 21h

mov ax,bx ; сохраняем индекс в ax

xor cx,cx ; cx - счетчик цифр

number_to_string:

xor dx,dx ; подготовка к делению

div c10 ; деление

add dx,30h ; в dx - ASCII-код остатка от деления

push dx ; сохраняем его в стеке

inc cx ; инкремент счетчика цифр

cmp ax,0 ; цикл, пока частное ненулевое

jne number_to_string

out_index_loop: ; цикл вывода индекса

pop dx ; извелекаем очередную цифру

mov ah,02h ; выводим ее на экран

int 21h

loop out_index_loop

end_program:

mov ah,4ch

int 21h

end start

25.Ввод с клавиатуры и умножение длинных чисел

.model small

.stack 100h

.data

num1 dd 0

num2 dd 0

proizv dd 0,0

msg1 db 0ah,0dh,"Vvedite pervoe chislo:",0ah,0dh,"$"

msg2 db 0ah,0dh,"Vvedite vtoroe chislo:",0ah,0dh,"$"

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

lea dx,msg1 ; вывод на экран msg1

mov ah,09h

int 21h

call input ; ввод первого числа

lea bx,num1 ; записываем введенное длинное число в num1:

mov word ptr[bx],si ; младшее слово

mov word ptr[bx+2],di ; старшее слово

lea dx,msg2 ; вывод на экран msg2

mov ah,09h

int 21h

call input ; ввод второго числа

lea bx,num2 ; записываем введенное длинное число

mov word ptr[bx],si

mov word ptr[bx+2],di

mov ax,word ptr num1 ; перемножение чисел (смотри конспект)

mul word ptr num2

mov word ptr proizv,ax

mov word ptr proizv+2,dx

mov ax,word ptr num1

mul word ptr num2+2

add word ptr proizv+2,ax

adc word ptr proizv+4,dx

mov ax,word ptr num1+2

mul word ptr num2

add word ptr proizv+2,ax

adc word ptr proizv+4,dx

mov ax,word ptr num1+2

mul word ptr num2+2

add word ptr proizv+4,ax

adc word ptr proizv+6,dx

mov ah,4ch

int 21h

input proc ; процедура ввода длинного числа

xor si,si ; возвращает число в di:si

xor di,di

loop1:

mov ah,01h

int 21h

cmp al,13

je end_input

sub al,30h

xor bx,bx

mov bl,al

mov ax,di

mul c10

mov di,ax

mov ax,si

mul c10

add ax,bx

adc dx,di

mov di,dx

mov si,ax

jmp loop1

end_input:

ret

input endp

end start

26. Обработка переполнения при делении чисел. Числа ввести с клавиатуры

Используя команды DIV и особенно IDIV, очень просто вызвать

пеpеполнение. Прерывания приводят (по крайней мара в системе, используемой

при тестировании этих программ) к непредсказуемым результатам. В операциях

деления предполагается, что частное значительно меньше, чем делимое.

Деление на ноль всегда вызывает прерывание. Но деление на 1 генерирует

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

Рекомендуется использовать следующее правило: если делитель - байт,

то его значение должно быть меньше, чем левый байт (AH) делителя: если

делитель - слово, то его значение должно быть меньше, чем левое слово (DX)

делителя. Проиллюстрируем данное правило для делителя, равного 1:

Операция деления: Делимое Делитель Частное

Слово на байт: 0123 01 (1)23

Двойное слово на слово: 0001 4026 0001 (1)4026

В обоих случаях частное превышает возможный размер. Для того чтобы

избежать подобных ситуаций, полезно вставлять перед командами DIV и IDIV

соответствующую проверку. В первом из следующих примеpов предположим, что

DIVBYTE - однобайтовый делитель, а делимое находится уже в регистре AX. Во

втором примере предположим, что DIVWORD - двухбайтовый делитель, а делимое

находится в регистровой паре DX:AX.

Слово на байт Двойное слово на байт

CMP AH,DIVBYTE CMP DX,DIVWORD

JNB переполнение JNB переполнение

DIV DIVBYTE DIV DIVWORD

Для команды IDIV данная логика должна учитывать тот факт, что либо

делимое, либо делитель могут быть отрицательными, а так как сравниваются

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

перевода отрицательного значения в положительное.

27. Дана строка в сегменте кода. Отсортировать методом выборки

.model small

.stack 100h

.code

start:

jmp continue

stroka db 254, 0 dup(255)

continue:

push cs

pop ds ; направляем ds на сегмент кода

mov bx,2

xor dx, dx

mov ah, 0Ah

int 21h

mov ah, 0dh

xor di,di

loop1:

mov al,stroka[bx]

cmp ah,stroka[bx+1] ; проверка, конец строки или нет

je end_program

mov si,bx

inc si

loop2: ; поиск

cmp ah,stroka[si]

je end_loop1

cmp al,stroka[si]

jna next_iter ; поиск

mov al,stroka[si] ; минимального

mov di,si ; элемента

next_iter:

inc si

jmp loop2

end_loop1:

mov dh,stroka[bx] ;перестановка

mov stroka[bx],al ;

mov stroka[di],dh

inc bx

jmp loop1

end_program:

mov ah,09h

lea dx,stroka

int 21h

mov ah,4ch

int 21h

end start

28 Транспонировать битовую матрицу использую операторы сдвига.

.model small

.stack 100h

.data

mes1 db 10,13,"Vvedite elementy matricy(8 elem)!!$"

mes2 db 10,13,"$"

mas db 8 dup(0)

mas_tr db 8 dup(0)

.code

begin:

mov ax,@data ;перемещаем сегмент данных в ах

mov ds,ax ;перемещаем сегмент данных в dx

lea dx,mes1 ;в dx адрес mes1

mov ah,9h ;вывод строкм mas1

int 21h

xor bx,bx

mov cx,8

again: ;ввод массива

mov ah,1

int 21h

sub al,'0'

mov mas[bx],al

inc bx

loop again ;повторение цикла again, пока сх не = 0

lea dx,mes2 ;адрес mes2 в dX

mov ah,9

int 21h

mov cx,8

xor bx,bx

xor dh,dh

output: ; вывод матрицы

mov dl,mas[bx]

add dx,30h

mov ah,2

int 21h

inc bx

loop output

mov cx,8

lea di,mas_tr

repeat: ;транспонирование

push cx

mov cx,8

lea si,mas

rep1:

rol BYTE PTR[si],1

rcl al,1

inc si

loop rep1

pop cx

mov [di],al

inc di

loop repeat

exit:

mov ah,4с00h

int 21h end begin

29. В сегменте данных дана матрица. Отсортировать ее побочную дигональ

.model small

.stack 100h

.data

razmer equ 4

matrix dw 1,2,3,13

dw 5,6,10,8

dw 9,7,11,12

dw 4,14,15,16

.code

start:

mov ax,@data

mov ds,ax

mov cx,razmer

dec cx

mov bx,cx

shl bx,1 ; bx - смещение (длина строки -2)

loop1:

mov si,bx

push cx

loop2:

mov dx,matrix[si] ;

mov di,matrix[si][bx] ; перестановка

cmp dx,di ;

jl cont_loop2

mov matrix[si],di

mov matrix[si][bx],dx

cont_loop2:

add si,bx ;

loop loop2 ; смещение на следующую строку

pop cx ;

loop loop1

lea dx,matrix

mov ah,4ch

int 21h

end start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Отсортировать элементы главной диагонали матрицы.

;

; 18.06.04

;

.model small

.stack 300h

.data

N equ 4 ; РАЗМЕР МАТРИЦЫ

THE_MATRIX db 'C', '1', '1', '1'

db '2', 'B', '2', '2'

db '3', '3', 'A', '3'

db '4', '4', '4', 'W','$'

str1 db 0dh,0ah,'$'

str2 db ' $'

.code

program:

mov ax, @data

mov ds, ax

mov cx, N

mov si, offset THE_MATRIX

push cx

mov cx, N

dec cx

;;;обычная сортировка пузырьком

sort_loop:

mov bx, si

add bx, N

inc bx

push cx

cmp_loop:

mov al, [si]

cmp al, [bx]

jna cont

mov dl, byte ptr [bx]

mov byte ptr [bx], al

mov byte ptr [si], dl

cont:

add bx, N

inc bx

loop cmp_loop

pop cx

add si, N

inc si

loop sort_loop

;;; Вывод матрицы

lea si,THE_MATRIX

mov cx,0

w3:

push cx

mov cx,0

w1:

mov ah,2

mov dx,[si]

int 21h

mov ah,9

lea dx,str2

int 21h

inc cx

cmp cx, n

je w2

inc si

jmp w1

w2:

mov ah,9

lea dx,str1

int 21h

inc si

pop cx

inc cx

cmp cl,n

jne w3

exit:

mov ax, 4c00h

int 21h

end program

30. Найти сумму элементов четных строк матрицы.

.model small

.stack 100h

.data

mes1 db 10,13,"Vvedite elementy matricy(5*4)!!$"

mes3 db 10,13,"Suuma 4etnyx strok(5*4):$",10,13

mes2 db 10,13,"$"

mas db 20 dup(0)

sum dw 5 dup(0)

.code

begin:

mov ax,@data

mov ds,ax

lea dx,mes1

mov ah,9h

int 21h

xor bx,bx

mov cx,20

again:

mov ah,1

int 21h

sub al,'0'

mov mas[bx],al

inc bx

loop again

lea dx,mes2

mov ah,9

int 21h

mov cx,20

xor bx,bx

xor dh,dh

output:

mov dl,mas[bx]

add dx,30h

mov ah,2

int 21h

inc bx

loop output

xor cx,cx

mov cl, 4 ;4islo strok

lea bx,mas ;adres matricy

add bx,4 ;perexod na 4etnuju str

mov si,0

p2: push cx

mov di,0

xor dx,dx ; dlja xranenija summy

mov cx,4 ; kol-vo stolbcov

p1:

mov al,[bx+di]

cbw

add dx,ax

inc di

loop p1

mov sum[si],dx

add si,2

add bx,8 ;na sled 4etnuju stroku

pop cx

dec cx

loop p2

xor dx,dx

lea dx,mes3

mov ah,9

int 21h

mov dx,sum[0]

add dx,30h

mov ah,09h

int 21h

mov dx,sum[2]

add dx,30h

mov ah,09h

int 21h

exit:

mov ah,4ch

int 21h

end begin

31 Ввести массив чисел, найти min и max, вывести на экран

.model small

.stack 100h

.data

massiv dw 80 dup(?)

msg1 db 0ah,0dh,"Vvodite chisla ",0ah,0dh,"$"

msg2 db 0ah,0dh,"max = $"

msg3 db 0ah,0dh,"min = $"

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

mov ah,09h ; вывод приглашения для ввода чисел

lea dx,msg1

int 21h

mov di,0 ; в di - max

mov si,32767 ; в si - min

xor dx,dx ; в dx - очередное число

input_loop:

mov ah,01h ; ввод символа

int 21h

cmp al,0dh ; если enter

je chislo ; то занести число в массив

cmp al,20h ; если пробел

je chislo ; то занести число в массив

sub al,30h ; вычитаем '0'

mov cl,al ; сохраняем цифру в cl

mov ax,dx ; в ax - введенное число

mul c10 ; умножаем на 10

xor ch,ch

add ax,cx ; добавляем цифру из al

mov dx,ax ; число снова в dx

jmp input_loop

chislo:

mov bx,cx ; в bx - порядковый номер очередного числа

shl bx,1 ; теперь - смещение очередного числа в массиве

mov massiv[bx],dx ; записываем в массив число

inc cx ; увеличиваем счетчик введенных чисел

cmp dx,si ; сравниваем число с минимальным

jb minimum ; если оно меньше, то jmp на minimum

cmp dx,di ; сравниваем число с максиальным

jg maximum ; если оно больше, то jmp на maximum

jmp chislo_cont ; иначе jmp на chislo_cont

minimum:

mov si,dx ; запоминаем минимальное число в si

jmp chislo_cont

maximum:

mov di,dx ; запоминаем максимальное число в di

chislo_cont:

xor dx,dx ; dx в ноль

cmp cx,80 ; если ввели 80-ое число

je end_input ; то конец ввода

cmp al,0dh ; если был нажат enter

je end_input ; то конец ввода

jmp input_loop

end_input:

mov ah,09h ; вывод на экран msg2

lea dx,msg2

int 21h

mov ax,di ; передаем в функцию output max через ax

call output ; выводим это число

lea dx,msg3 ; вывод на экран msg3

mov ah,9

int 21h

mov ax,si ; передаем в ouptput min через ax

call output ; выводим это число

mov ah,4ch ; завершение программы

int 21h

output proc ; процедура вывода числа, находящегосы в ax

xor cx,cx ; счетчик цифр

div_loop:

xor dx,dx ; подготовка к делению

div c10 ; деление

add dx,30h ; в dx - ASCII-код остатка от деления

push dx ; сохраняем его в стеке

inc cx ; инкремент счетчика

cmp ax,0 ; деление, покуда частное не нулевое

je out_loop

jmp div_loop

out_loop: ; цикл вывода числа

pop dx ; извлекаем из стека очередной остаток

mov ah,02h ; и выводим его на экран

int 21h

loop out_loop ; цикл продолжается cx раз

ret

output endp

end start

32. В сегменте данных расположены числа в формате двойного слова. С клавиатуры вводится число и определяется, имеется ли это число в сегменте данных.

.model small

.stack 100h

.data

massiv dd 12345678,13579246,24681357

chislo dd 0

c10 dw 10

str1 db 0ah,0dh,"Vvedite chislo:",0ah,0dh,'$'

str2 db 0ah,0dh,"Vvedennoe chislo ne naydeno.",0ah,0dh,'$'

str3 db 0ah,0dh,"Vvedennoe vami chislo naydeno!",'$'

.code

.386

start:

mov ax,@data

mov ds,ax

mov ah,09h

lea dx,str1

int 21h

input_loop:

mov ah,01h

int 21h

cmp al,0dh

je end_input

sub al,30h

xor bx,bx

mov bl,al

xor dx,dx ; ввод длинного числа

mov ax,word ptr[chislo+2]

mul c10

mov word ptr[chislo+2],ax

mov ax,word ptr[chislo]

mul c10

add dx,word ptr[chislo+2]

add ax,bx

mov word ptr[chislo],ax

mov word ptr[chislo+2],dx

jmp input_loop

end_input:

mov cx,offset chislo ; в сх - количество чисел

sub cx,offset massiv

shr cx,2

mov ax,word ptr[chislo] ; в ax - младшее слово числа

mov dx,word ptr[chislo+2] ; в dx - старшее слово числа

cmp_loop: ; цикл сравнения

mov bx,cx

dec bx

shl bx,2

add bx,offset massiv

cmp ax,word ptr[bx]

je continue_cmp

jmp cmp_end

continue_cmp:

add bx,2

cmp dx,word ptr[bx]

je find

cmp_end: ; если ничего не найдено

loop cmp_loop

mov ah,09h

mov dx,offset str2

int 21h

jmp end_start

find: ; если число найдено

mov ah,09h

mov dx,offset str3

int 21h

end_start:

mov ah,4ch

int 21h

end star

33. Ввести массив чисел и отсортировать методом пузырька

.model small

.stack 100h

.data

massiv dw 80 dup(?)

msg db "Vvodite chisla cherez probel, okonchanie vvoda - ENTER",0ah,0dh,'$'

c10 dw 10

.code

start:

mov ax,@data

mov ds,ax

mov ah,09h ; вывод msg

lea dx,msg

int 21h

xor bx,bx ; bx - смещение в массиве вводимого числа

xor dx,dx ; dx - вводимое число

input_loop:

mov ah,01h ; считваем очередной символ

int 21h

cmp al,0dh ; если это enter

je chislo

cmp al,20h ; или пробел

je chislo

sub al,30h ; иначе - получаем цифру

mov cl,al ; сохраняем ее в cl

mov ax,dx ; в ax - вводимое число

mul c10 ; умножаем на 10

xor ch,ch

add ax,cx ; добавляем к результату последнюю цифру

mov dx,ax ; в dx - полученное число

jmp input_loop

chislo: ; если окончен ввод числа

mov massiv[bx],dx ; запись этого числа в массив

add bx,2 ; смещаемся к следующему элементу

cmp bx,160 ; если массив заполнен

je end_input ;

cmp al,0dh ; или последнее число

je end_input ; то конец ввода

xor dx,dx ; обнуляем dx для ввода следующего числа

jmp input_loop

end_input:

mov cx,bx ; в cx - (количество введенных чисел + 1) * 2

shr cx,1 ; cx = cx \ 2

dec cx ; теперь в cx - количество введенных чисел

call sort ; сортировка

mov ah,4ch

int 21h

sort proc

loop1:

xor bx,bx ; bx - смещение в массиве

push cx ; сохраняем cx в стеке

loop2:

mov ax,massiv[bx]

cmp ax,massiv[bx][2] ; сравниваем два соседних элемента

jl cont_loop2 ; если правый больше левого, то продолжить цикл

mov dx,massiv[bx][2] ; иначе - перестановка

push massiv[bx][2]

push massiv[bx]

pop massiv[bx][2]

pop massiv[bx]

cont_loop2:

add bx,2 ; смещаемся к следующему элементу в массиве

loop loop2

pop cx ; восстанавливаем cx

loop loop1

ret

sort endp

end start

34.Вывести строку в обратном порядке.

.model small

.stack 100h

.data

msg1 db 0Ah,0Dh,"Enter string <80(char)",0Ah,0Dh,'$'

string db 80 dup(?)

msg2 db 0Ah,0Dh,"Reversing string",0Ah,0Dh,'$'

.code

start: mov ax,@data

mov ds,ax

lea dx,msg1

mov ah,09h

int 21h

mov cx,80

xor si,si

l1: mov ah,01h

int 21h

cmp al,0Dh

je continue

mov string[si],al

inc si

loop l1

continue: mov ah,09h

lea dx,msg2

int 21h

cmp si,0

je exit

dec si

mov cx,si

l2: mov si,cx

mov dl,string[si]

mov ah,02h

int 21h

loop l2

mov dl,string[0]

mov ah,02h

int 21h

exit:

mov ah,4Ch

int 21h

end start

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

.model small

.stack 256

.data

mas dw 8 dup(0)

zz db 0Dh, 0Ah,'-$'

.code

start:

mov ax,@data

mov ds,ax

mov cx,8

mas_in:

xor bx,bx

num_s_in:

cmp bx,6

je end_num_s_in

mov ah,01h

int 21h

cmp al,0Dh

je end_num_s_in

inc bx

xor ah,ah

push ax

jmp num_s_in

end_num_s_in:

mov bp,1

xor di,di

num_p:

cmp bx,1

je end_num_p

pop ax

sub al,'0'

mul bp

add di,ax

mov ax,bp

mov bp,10

mul bp

mov bp,ax

dec bx

jmp num_p

end_num_p:

pop ax

cmp al,'-'

jne ee

neg di

ee:

mov ax,cx

;sub ax,2

shl ax,1

mov si,offset mas

add si,ax

mov word ptr [si],di

loop mas_in

____SOBSTVENNO SLOGENIE____

mov di,offset mas

xor ax,ax ;summa bolhih 0

xor bx,bx ;summa menshih 0

mov cx,9

add_num:

cmp word ptr[di],0

jl add_less_zero

add ax,word ptr [di]

jmp e

add_less_zero:

add bx,word ptr [di]

e:

add di,2

loop add_num

___VYVOD_______

div_num_s:

mov cx,10

xor bp,bp

div_num:

cmp ax,0

je end_div_num

xor dx,dx

div cx

add dx,'0'

push dx

inc bp

jmp div_num

end_div_num:

vyvod:

cmp bp,0

je end_vyvod

pop ax

mov ah,02h

mov dl,al

int 21h

dec bp

jmp vyvod

end_vyvod:

cmp bx,0

je exit

neg bx

mov ah,9

mov dx,offset zz

int 21h

mov ax,bx

xor bx,bx

jmp div_num_s

exit:

mov ax,4C00h

int 21h end start

36.Дан массив строк. Найти строку с max длинной и вывести ее на экран.

.model small

.stack 100h

.data

str0 db "Hello",'$'

str1 db "Good day",'$'

str2 db "Hi!",'$'

str3 db "How do you do?",'$'

str4 db "I greet you",'$'

StrArray dw offset str0

dw offset str1

dw offset str2

dw offset str3

dw offset str4

StrCount dw 5

.code

program:

mov ax, @data

mov ds, ax

mov si, offset StrArray ; si - начало массива строк

mov cx, StrCount ; инициализация счетчика

xor ax, ax ; в ax - макс. длина строки

calc_length:

mov bx, [si] ; bx - смещение текущей строки

add si, 2 ; si сдвигается на следующую строку

push cx ; сохраняем счетчик

call str_len ; определяем длину строки

cmp ax, cx

ja end_loop ; если найденная длмна больше макс.

mov ax, cx ; сохраняем эту длину в ax

mov dx, bx ; сохраняем в dx смещение строки

end_loop:

pop cx ; восстанавливаем счетчик

loop calc_length

mov ah, 9 ; выводим макс. строку на экран

int 21h

mov ax, 4c00h

int 21h

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Находит длину строки

; bx - смещение строки

; Результат: cx - искомая длина

str_len proc near

push bx

push ax

xor cx, cx

mov al, '$'

mov ah, 0

len_lp:

cmp al, [bx]

je end_len

cmp ah, [bx]

je end_len

inc cx

inc bx

jmp len_lp

end_len:

pop ax

pop bx

ret

str_len endp

end program

37. Перевод числа из одной системы счисления в другую. Данные вводить с клавиатуры.

.modl small

.stack 256

.data

Mess1 db 'Enter number in 10c: $'

Mess2 db 0Dh, 0Ah,'Result in 16c: $'

.code

start:

mov ax,@data

mov ds,ax

mov ah,9

mov dx,offset Mess1

int 21h; Выводим первое сообщение

xor bx,bx

num_in:

; Вводим символы числа, пока не нажмется энтэр

mov ah,01h

int 21h

cmp al,0Dh

je end_num_in

sub al,'0' ; переводим в десятичный вид

xor ah,ah

push ax ; и ложим его в стек

inc bx

jmp num_in

end_num_in:

mov cx,1

num_preobr:

cmp bx,0

je end_num_preobr ; если цифры ;числа закончились, то переходим на ;end_num_preobr

pop ax

xor dx,dx ; умножаем на число в cx (1, 10, 100, 1000, …)

mul cx

; и добавляем к конечному числу

add di,ax

dec bx

; умножаем на 10, чтобы получить 10, 100, 1000, …

mov ax,10

mul cx

mov cx,ax

jmp num_preobr

end_num_preobr:

; Выводится сообщение 2

mov ah,9

mov dx,offset Mess2

int 21h

; начало коныертации в 16 систему

mov ax,di

mov bx,0

mov cx,16

num_convert:

; непосредственно перевод

cmp ax,0

je end_convert

xor dx,dx

; делим на систему счисления

div cx

; сравниваем остаток от деления с 9, если больше, добавляем ‘7’, иначе ‘0’

cmp dx,9

ja above_9

add dx,'0'

jmp next

above_9:

add dx,'7'

next:

push dx

inc bx

jmp num_convert

end_convert:

out_num:

; если цифры закончились, то переходим ;на end_out_num

cmp bx,0

je end_out_num

pop dx

mov ah,02h

int 21h

dec bx

jmp out_num

end_out_num:

mov ax,4C00h

int 21h

end start

38.Вычислить сумму столбцов матрицы с полным вводом/выводом (программа типа exe)

.model small

.stack 300h

.code

endl macro

push ax dx

mov ah, 02h

mov dl, 0Ah

int 21h

mov dl, 0Dh

int 21h

pop dx ax

endm

outint macro value

local outint_l1, outint_l2

push ax bx cx dx

mov ax, value

mov bx, 10

xor cx, cx

outint_l1:

xor dx, dx

div bx

push dx

inc cx

cmp ax, 0

jne outint_l1

mov ah, 02h

outint_l2:

pop dx

add dl, '0'

int 21h

loop outint_l2

pop dx cx bx ax

endm

proc readint

push cx si bx dx

mov buf_str, 8

mov ah, 0Ah

lea dx, buf_str

int 21h

xor cx, cx

mov si, 2

xor ax, ax

mov bx, 10

in_loop:

mul bx

mov dl, [buf_str+si]

sub dl, '0'

add ax, dx

inc si

inc cl

cmp cl, [buf_str+1]

jl in_loop

pop dx bx si cx

endl

ret

endp

start:

mov ax, @data

mov ds, ax

xor cx, cx

xor dx, dx

xor di, di

input_loop:

push dx

mov ah, 09h

lea dx, str_1

int 21h

outint cx

lea dx, str_2

int 21h

mov si, sp

mov dx, [ss:si]

outint dx

lea dx, str_3

int 21h

call readint

mov word ptr matrix[di], ax

add di, 2

pop dx

inc cx

cmp cx, N

jl input_loop

xor cx, cx

inc dx

cmp dx, N

jl input_loop

xor ax, ax

cont_summ:

mov si, ax

shl si, 1

xor dx, dx

cont_summ_2:

add dx, word ptr matrix[si]

add si, N*2

cmp si, N*N*2

jl cont_summ_2

outint dx

endl

inc ax

cmp ax, N

jl cont_summ

mov ax, 4C00h

int 21h

.data

N equ 3

matrix db N*N*2 dup(?)

buf_str db 10 dup(?)

str_1 db "Input matrix[$"

str_2 db "][$"

str_3 db "]:",10,13,"$"

sum1 dw 0

sum2 dw 0

end start

39. Перевод строки в число.

.model small

.stack 100h

.data

num dw ?

c10 db 10

.code

begin:

mov ax,@data

mov ds,ax

xor bx,bx

again:

mov ah,1

int 21h

cmp al, 0dh ; если энтер, то закончим ввод

je con

sub al,'0' ; вычитаем ‘0’ из символа для

xor ah,ah ;

mov si,ax

mov ax,bx ; помещаем конечный на данный момент результат в ax

mul c10 ; и умножаем его на 10

add ax,si ; добавляем к полученному значению введенную только что цифру

mov bx, ax ; формируем в bx конечное на данный момент значение

jmp again ; зацикливаем

con:

mov num,bx ; полученное число

mov ax, 4c00h

int 21h

end begin

40. В сегменте данных дана матрица. Отсортировать ее побочную дигональ

.model small

.stack 100h

.data

razmer equ 4

matrix dw 1,2,3,13

dw 5,6,10,8

dw 9,7,11,12

dw 4,14,15,16

.code

start:

mov ax,@data

mov ds,ax

mov cx,razmer

dec cx

mov bx,cx

shl bx,1 ; bx - смещение (длина строки -2)

loop1:

mov si,bx

push cx

loop2:

mov dx,matrix[si] ;

mov di,matrix[si][bx] ; перестановка

cmp dx,di ;

jl cont_loop2

mov matrix[si],di

mov matrix[si][bx],dx

cont_loop2:

add si,bx ;

loop loop2 ; смещение на следующую строку

pop cx ;

loop loop1

lea dx,matrix

mov ah,4ch

int 21h

end start

41.Вводится матрица чисел. Найти сумму элементов по каждой диагонали и вывести на экран.

.model small

.stack 300h

.code

endl macro

push ax dx

mov ah, 02h

mov dl, 0Ah

int 21h

mov dl, 0Dh

int 21h

pop dx ax

endm

outint macro value

local outint_l1, outint_l2

push ax bx cx dx

mov ax, value

mov bx, 10

xor cx, cx

outint_l1:

xor dx, dx

div bx

push dx

inc cx

cmp ax, 0

jne outint_l1

mov ah, 02h

outint_l2:

pop dx

add dl, '0'

int 21h

loop outint_l2

pop dx cx bx ax

endm

proc readint

push cx si bx dx

mov [buf_str], 8

mov ah, 0Ah

lea dx, buf_str

int 21h

xor cx, cx

mov si, 2

xor ax, ax

mov bx, 10

in_loop:

mul bx

mov dl, [buf_str+si]

sub dl, '0'

add ax, dx

inc si

inc cl

cmp cl, [buf_str+1]

jl in_loop

pop dx bx si cx

endl

ret

endp

start:

mov ax, @data

mov ds, ax

xor cx, cx

xor dx, dx

xor di, di

input_loop:

push dx

mov ah, 09h

lea dx, str_1

int 21h

outint cx

lea dx, str_2

int 21h

mov si, sp

mov dx, [ss:si]

outint dx

lea dx, str_3

int 21h

call readint

mov word ptr matrix[di], ax

add di, 2

pop dx

inc cx

cmp cx, N

jl input_loop

xor cx, cx

inc dx

cmp dx, N

jl input_loop

xor si, si

xor ax, ax

count_sum1:

add ax, word ptr matrix[si]

add si, N*2+2

cmp si, N*N*2

jl count_sum1

mov sum1, ax

mov si, N*2-2

xor ax, ax

count_sum2:

add ax, word ptr matrix[si]

add si, N*2-2

cmp si, N*(N-1)*2+2

jl count_sum2

mov sum2, ax

mov ah, 09h

lea dx, str_4

int 21h

outint sum1

lea dx, str_5

int 21h

outint sum2

lea dx, str_6

int 21h

mov ax, 4C00h

int 21h

.data

N equ 3

matrix db N*N*2 dup(?)

buf_str db 10 dup(?)

str_1 db "Input matrix[$"

str_2 db "][$"

str_3 db "]:",10,13,"$"

str_4 db "Sum1=$"

str_5 db 10,13,"Sum2=$"

str_6 db 10,13,"$"

sum1 dw 0

sum2 dw 0

end start

42. Работа с окнами в текстовом режиме.

Работа с окнами в текстовом режиме. (результат работы проги: синее окно,

;в нем - зеленое окно, в зеленом окне - текст :))

.MODEL small

.STACK 100h

.DATA

str_ db 'TEXT'

len equ $-str_

.CODE

main:

mov ax, @data

mov ds, ax

mov es, ax

mov ah, 06h ;очистка окна

mov al, 00h ;режим окна

mov bh, 17h ;видео-атрибут для пустых строк

mov cx, 0000h ;очистка экрана от (00;00) до (24;79)

mov dx, 1b4fh

int 10h

mov ax, 0600h ;в ah - 06h в al - 00h

mov bh, 20h

mov cx, 0a1ch

mov dx, 0c31h

int 10h

mov ah, 13h ;вывод на экран в позиции курсора

mov al, 0 ;не менять положение курсора

mov bh, 0 ;номер страницы

mov bl, 07h ;цвет выводимого текста

mov cx, len

mov dx, 0b25h ;координаты на экране (dh - y, dl - x)

lea bp, str_ ;адрес выводимой строки

int 10h

mov ah, 4ch

int 21h

end main

43.Сложение и вычитание длинных чисел.

.model small

.stack 100h

.data

num1 dw 1234h, 5678h

num2 dw 8765h, 4321h

res1 dw 0,0

res2 dw 0,0

.code

start:

mov ax, @data

mov ds, ax

; сложение

mov ax, num1[0]

add ax, num2[0]

mov res1[0], ax

mov ax, num1[2]

adc ax, num2[2]

mov res1[2], ax

; вычитание

mov ax, num1[0]

sub ax, num2[0]

mov res2[0], ax

mov ax, num1[2]

sbb ax, num2[2]

mov res2[2], ax

mov ax, 4C00h

int 21h

end start

44. Вывести на экран ASCII символы по 16 символов с строке. Использовать прямой доступ к видеопамяти.

.model tiny

.code

.386 ;команды для 386 процессора

org 100h

start:

mov ax,003 ;установка 3 видео режима

int 10h ;очистка экрана

cld ; обработка строк в прямом порядке

mov eax,1F201F00h ;первый символ

mov bx, 0F20h ;

mov cx,255 ;количество символов

mov di, offset ctable ; буфер для записи кодов

cloop:

stosd

inc al

test cx, 0Fh ; кратно ли cx 16

jnz continue loop ; продолжение цикла

push cx

mov cx, 80-32 ; осталось мест в строке

xchg ax,bx

rep stows

xchg bx,ax

pop cx

continue_loop:

loop cloop

stosd ; регистров в адрес приёмника si,di

mov ax,0B800h ; вывод на экран

mov ex,ax ;устанавливаем на текст буфер

xor di,di ;es :di- буфер приёмника

mov si,offset ctable ; ds:si буфер

mov cx,15*80*32 ;количество выводимых слов

rep movsw ;пересылка

ret

ctable: end start

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

.model small

.stack 100h

.data

STR_LEN equ 20

string1 db STR_LEN dup ('0')

db '$'

.code

start:

mov ax, @data

mov ds, ax

mov ax, cs

mov es, ax

mov si, offset string1

mov di, offset string2

mov cx, STR_LEN

cld

rep movsb

mov ax, 4c00h

int 21h

string2 db STR_LEN dup ('2')

db '$'

end start

46.Ввести массив символов, выделить из него числа и сложить их.

.model small

.stack 100h

.code

endl macro

mov ah, 02h

mov dl, 0Ah

int 21h

mov dl, 0Dh

int 21h

endm

start:

mov ax, @data

mov ds, ax

mov [buffer], 99

mov ah, 0Ah

int 21h

mov si, 2

xor ch, ch

mov cl, [buffer+1]

xor ax, ax

str_loop:

mov dl, [buffer+si]

cmp dl, '0'

jl not_int

cmp dl, '9'

jg not_int

xor dh, dh

sub dl, '0'

push dx

mov bx, 10

mul bx

pop dx

add ax, dx

jmp no_add

not_int:

cmp ax, 0

je no_add

add sum, ax

xor ax, ax

no_add:

inc si

loop str_loop

cmp ax, 0

je no_add_2

add sum, ax

no_add_2:

; out int sum

endl

mov ax,sum

mov bx, 10

xor cx, cx

cont_out:

xor dx, dx

div bx

push dx

inc cx

cmp ax, 0

jne cont_out

mov ah, 02h

out_loop:

pop dx

add dl, '0'

int 21h

loop out_loop

endl

mov ax, 4C00h

int 21h

.data

buffer db 100 dup(?)

sum dw 0

end start

47. ввести 2 строки и сравнить их

.model small

.stack 100h

.data

msg1 db 0Ah,0Dh,"Enter first string",0Ah,0Dh,'$'

msg2 db 0Ah,0Dh,"Enter second string",0Ah,0Dh,'$'

msg4 db 0Ah,0Dh,"equal strings",0Ah,0Dh,'$'

msg5 db 0Ah,0Dh,"str1>str2",0Ah,0Dh,'$'

msg6 db 0Ah,0Dh,"str1<str2",0Ah,0Dh,'$'

str1 db 80 dup(0)

str2 db 80 dup(0)

.code

start:

push @data

pop ds

mov ah , 09h

mov dx,offset msg1

int 21h

xor si,si

xor di,di

mov cx,80

enter_str1:

mov ah,01h

int 21h

cmp al,0Dh

je continue_str2

mov str1[si],al

inc si

loop enter_str1

continue_str2:

mov cx,80

mov str1[si],'$'

mov ah,09h

lea dx,msg2

int 21h

xor di,di

enter_str2:

mov ah,01h

int 21h

cmp al,0Dh

je continue

mov str2[di],al

inc di

loop enter_str2

continue:

mov cx,80

mov str2[di],'$'

xor di,di

call my_proc

mov ah,09h

int 21h

mov ax,04C00h

int 21h

my_proc proc

xor di,di

comparable:

mov al,str1[di]

cmp al,str2[di]

jl large_str2

jg large_str1

inc di

loop comparable

lea dx,msg4

ret

large_str1:

lea dx,msg5

ret

large_str2:

mov ah,09h

lea dx,msg6

ret

my_proc endp

end start

52. Определить, входит ли в строку, определенную в сегменте данных, подстрока, введенная с клавиатуры. Результат работы программы – текст соответствующего сообщения.

.MODEL small

.STACK 100h

.DATA

msg1 DB "Enter string: $"

msg2 DB 0Ah, 0Dh, "Enter substring to find: $"

msg3 DB 0Ah, 0Dh, "Yes!$"

msg4 DB 0Ah, 0Dh, "No such substring:($"

str1ml DB 200

str1l DB '$'

str1 DB 200 dup('$')

str2ml DB 200

str2l DB '$'

str2 DB 200 dup('$')

.CODE

begin:

mov ax, @data

mov ds, ax

mov es,ax

xor ax,ax

lea dx, msg1 ;вывод приглашения msg1

call strout

lea dx, str1ml ;ввод строки str1

call strin

lea dx, msg2 ;вывод приглашения msg2

call strout

lea dx, str2ml ;ввод строки str2

call strin

xor cx, cx

mov cl, str1l ;устанавливается кол-во повторений

sub cl, str2l

inc cl

cld ;обход вперёд

lea di, str2 ;в di - строка, которую надо найти

lea si, str1 ;в si - строка, в которой ищем

xor ax, ax

all_string: ;повторяется для str1 до конца строки минус длина str2

push cx

push di

push si

mov bx, si

mov cl, str2l

repe cmpsb

je _eq

jne _neq

_eq:

lea dx, msg3 ;вывод приглашения msg1

call strout

jmp _end

;inc al

_neq:

pop si

pop di

pop cx

inc si

loop all_string

lea dx, msg4

call strout

_end:

mov ah, 4ch ;канэц, просто канэц какой-та

int 21h

;*****************Процедуры***********************

;*************************************************

strin proc

mov ah, 0Ah

int 21h

ret

strin endp

;*************************************************

strout proc

mov ah, 09h

int 21h

ret

strout endp

;*************************************************

end begin

53. Выполнить реверс слов строки, определенной в сегменте данных (кода). Результат вывести.

; reverse string

name "reverse"

org 100h

jmp start

string1 db 255 dup('$')

newstr db 0ah, 0dh, '$'

instr db "enter string:",0Dh,0Ah,'$'

start: mov dx,offset instr ;instruction

mov ah,09h

int 21h

mov bx,offset string1 ;vvod

mov [bx],255

mov dx, bx

mov ah,0Ah

int 21h

add bl, string1[1]

add bx, 2

mov [bx],'$'

xor dx,dx

xor ax,ax

lea bx, string1

add bx, 2

mov si, bx

mov di, bx

dec si

next_byte: inc si ;prohod po stroke

mov al,[si]

cmp al,' '

je found_the_end

mov al, [si]

cmp al,'$'

je found_the_end

jmp next_byte

found_the_end: mov dx,si ;naiden probel ili $

dec si

mov bx, di

do_reverse: cmp bx, si ;inversia slova

jae done

mov al, [bx]

mov ah, [si]

mov [si], al

mov [bx], ah

inc bx

dec si

jmp do_reverse

done: mov si,dx ;rezult

inc dx

mov bx,dx

mov di,bx

mov al,[si]

mov dx, offset newstr

mov ah, 09h

int 21h

mov dx,offset string1

add dx,2

mov ah, 09h

int 21h

mov ah,[si]

cmp ah,'$'

jne next_byte

mov ah, 0

int 16h

ret

.model small ;размер блока памяти (тут для ехе-программы)

.stack 100h ;для данных и стека

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

msg1 db 0Ah,0Dh,"Enter string :",0Ah,0Dh,'$'

string db 80 dup(?) ;неинециализированная переменная

msg2 db 0Ah,0Dh,"Reversed string:",0Ah,0Dh,'$'

.code ;сегмент кода

start: ;начало куска старт

mov ax,@data ;адрес начала сегмента данных

mov ds,ax ;

lea dx,msg1

mov ah,09h

int 21h ;вызов дос-прерывания

vvod:

mov ah,01h

int 21h

cmp al,0Dh ;сравнение

je body ;и если символ равен вводу, то дальнейшее перенаправление

mov string[si],al ;заносим символы в строку

inc si ;si++

loop vvod ;повторять блок vvod

body:

mov ah,09h

lea dx,msg2 ;копирование адресса

int 21h ;вывод текста оформления

cmp si,0

je exit

mov di,si ;создание третьего счётчика(si - второй, cx - конечно первый, но он тут неиспользуется ввиду того что он начинает изменяться в любом цикле, а тут алгоритм сложнее

revers: ;функция для перемещения по строке

dec si ;si--

mov bp,si

cmp string[si], ' ' ;сравнение для нахождения пробела между словами

je funk

cmp si,0 ;проверка второго счётчика на конец строки

je funk3

loop revers

mov dl,string[0] ;допись последнего символа

mov ah,02h

int 21h

funk: ;функция для вывода слова

inc bp

mov dl,string[bp]

mov ah,02h

int 21h

cmp bp,di

je funk2

loop funk

funk2: ;функция для изменения di и дальнейшего направления в revers

mov di,si

je revers

funk3: ;функция для вывода первого слова перед которым нет пробела

mov dl,string[bp]

mov ah,02h

int 21h

cmp bp,di

je exit

inc bp

loop funk3

exit:

mov ah,4Ch ;копирование для конца проги

int 21h ;вызов дос-прерывания

end start ;собственно сам конец проги

54. Отсортировать слова в строке (по длине слова, по алфавиту).

.model small;

.stack 100h;

.data;

i dw 0h

String db 'Enter a line: $'

Stg db 100h dup(0h); Массив для строки

.code;

mov ax, @data;

mov ds, ax;

mov ah, 00h; Очистка экрана

mov al, 2h;

int 10h

mov ah, 09h

Lea dx, String

int 21h

mov ah, 1h; Ф-я ввода символа

mov si, 0h

mov bx, 0h

Input: ;Ввод массива

int 21h

mov cx, si

mov Stg[bx], cl; Длина слова

cmp al, 32; Проверка на пробел

jne Skip1

mov si, 0h

add bx, 10h; Начало следующего слова

jmp Input

Skip1:

inc si

mov Stg[bx+si], al; Помещение символа в массив

cmp al, 13

jne Input

mov Stg[bx+si], 0h; Удаление Enter'а

mov i, bx; Кол-во слов

mov bx, 0h

Sort1: ;Выборочная сортировка

mov di, bx; Индекс минимальной длины

mov ax, bx

add ax, 10h

Sort2:

mov si, ax

mov cl, Stg[si]

cmp cl, Stg[di]

jae Skip2

mov di, si; Если меньше

Skip2:

add ax, 10h

cmp ax, i

jbe Sort2

mov si, 0h

Sort3:

moV cl, Stg[bx+si]; Смена слов

mov al, Stg[di]

mov Stg[bx+si], al

mov Stg[di], cl

inc si

inc di

cmp si, 10h

jb Sort3

add bx, 10h

cmp bx, i

jb Sort1

mov ah, 02h; Ф-я установки позиции курсора:

mov bh, 0h; № Страницы

mov dh, 2h; № строки

mov dl, 0h; № столбца

int 10h

mov bx, 0h

mov si, 0h

mov ah, 2h; Ф-я вывода символа

Output: ;Вывод массива

inc si

mov dx, word ptr Stg[bx+si]

cmp dx, 0h

jne Skip3

cmp bx, i

je Exit

mov si, 0h

add bx, 10h

mov dx, ' '

Skip3:

int 21h

cmp bx, i

jbe Output

Exit:

mov ah, 4ch;

int 21h

End

55. Удалить из строки заданное слово.

.MODEL small

.STACK 100h

.DATA

msg1 DB "Enter string: $"

msg2 DB 0Ah, 0Dh, "Enter substring to delete: $"

msg3 DB 0Ah, 0Dh, "Result: $"

str1ml DB 200

str1l DB '$'

str1 DB 200 dup('$')

str2ml DB 200

str2l DB '$'

str2 DB 200 dup('$')

.CODE

begin:

mov ax, @data

mov ds, ax

mov es,ax

xor ax,ax

lea dx, msg1 ;вывод приглашения msg1

call strout

lea dx, str1ml ;ввод строки str1

call strin

lea dx, msg2 ;вывод приглашения msg2

call strout

lea dx, str2ml ;ввод строки str2

call strin

xor cx, cx

mov cl, str1l ;устанавливается кол-во повторений

sub cl, str2l

inc cl

cld ;обход вперёд

lea di, str2 ;в di - строка, которую надо найти

lea si, str1 ;в si - строка, в которой ищем

xor ax, ax

all_string: ;повторяется для str1 до конца строки минус длина str2

call sub_search

inc si

loop all_string

call nextstr

;xor dx, dx

;mov dl, al

;add dl, 30h

;mov ah, 02h

;int 21h

lea dx, msg3

call strout

lea dx, str1

call strout

_end:

mov ah, 4ch ;канэц, просто канэц какой-та

int 21h

;*****************Процедуры***********************

nextstr proc

push dx

push ax

mov dl, 0Dh ;перевод на другую строку

mov ah, 02h

int 21h

mov dl, 0Ah

mov ah, 02h

int 21h

pop ax

pop dx

ret

nextstr endp

;*************************************************

strin proc

mov ah, 0Ah

int 21h

ret

strin endp

;*************************************************

strout proc

mov ah, 09h

int 21h

ret

strout endp

;*************************************************

sub_search proc

push cx

push di

push si

mov bx, si

mov cl, str2l

repe cmpsb

je _eq

jne _neq

_eq:

;di указывает на строку 2, si указывает на конец слова, которое надо удалить

call delete

inc al

_neq:

pop si

pop di

pop cx

ret

sub_search endp

;*************************************************

delete proc

push bx

push di

push si

mov di, bx ;в di - адрес начала удаляемого слова

xor cx, cx

mov cl, str1l

repe movsb

pop si

pop di

pop bx

ret

delete endp

end begin

.MODEL small

.STACK 100h

.DATA

msg1 DB "Enter string: $"

msg2 DB 0Ah, 0Dh, "Enter symbol: $"

msg3 DB 0Ah, 0Dh, "Result: $"

str1ml DB 200

str1l DB '$'

str1 DB 200 dup('$')

symbol DB ?

.CODE

begin:

mov ax, @data

mov ds, ax

mov es,ax

xor ax,ax

lea dx, msg1

call strout

lea dx, str1ml

call strin

lea dx, msg2

call strout

mov ah, 01h

int 21h

mov [symbol], al

xor cx, cx

mov cl, str1l

xor si, si

xor di, di

xor bx, bx

mov di, offset str1

mov si, offset str1

mov bl, [symbol]

cld

main_loop:

cmp [si], ' ' ;esli probel

je cont ;propuskaem

cmp [si], 13 ;esli konec

je end_main_loop ;vyvodim stroku

cmp [si], bl

jne cont ;esli ne sovpalo

in_loop:

inc si

cmp [si], ' ' ;esli probel

je stop ;stop

cmp [si], 13 ;esli konec

je stop ;stop

dec cx

jmp in_loop

stop:

call delete ;udalyaem

cont:

mov di, si

inc si

loop main_loop

end_main_loop:

lea dx, msg3

call strout

lea dx, str1

call strout

_end:

mov ah, 4ch ;vyhod

int 21h

;*****************Процедуры***********************

nextstr proc

push dx

push ax

mov dl, 0Dh

mov ah, 02h

int 21h

mov dl, 0Ah

mov ah, 02h

int 21h

pop ax

pop dx

ret

nextstr endp

;*************************************************

strin proc

mov ah, 0Ah

int 21h

ret

strin endp

;*************************************************

strout proc

mov ah, 09h

int 21h

ret

strout endp

;*************************************************

;v si - index nachala podstroki

;v di - index konca

delete proc

push bx

push di

push si

push cx

xor cx, cx

mov cl, str1l

repe movsb

pop cx

pop si

pop di

pop bx

ret

delete endp

end begin

58. В массиве подсчитать число элементов, лежащих в заданном диапазоне.

.model small

.stack 100h

.data

left db 0h

right db 0h

count db 0h

mas_num = 5; number of element in mass

mass db mas_num dup(?)

outbuf db 4 dup(?),'$'

inbuf db 3,0,3 dup(?),'$'

ent db 0ah,0dh,'$'

massInput db "Input 30 elements if array - ", 0dh, 0ah, '$'

limInput db "Input limints - ", 0dh, 0ah, '$'

doneMess db "Done! Count - ", 0dh, 0ah, '$'

mesError db 0ah,0dh,'Number transormation error!',0ah,0dh,'$'

.code

printNum proc ;Вывод числа, размер числа байт

push ax ;поместить используемые регистры в стек

push bx

push si

push cx

;заполнить буфер пробелами

mov cx,4 ;количество элементов в буфере

mov si,offset outbuf;адрес буфера

space:

mov byte ptr [si],' ' ;записать пробел

inc si ;перейти к следующему элементу

loop space

mov si, offset outbuf[3];адрес буфера для вывода

mov bx, 10 ;коэффициент для деления

make_str:

xor ah,ah ;ah=0

div bl ;al=ax/bl

or ah,30h ;преобразовать цифру в символ

dec si ;перейти к следующему символу

mov [si],ah ;сохранить в строке

test al, al ;проверить ax=0

jnz make_str ;если не равен, то далее

mov ax, 0900h ;вывести число

mov dx, offset outbuf

int 21h

pop cx ;извлечь используемые регистры из стека

pop si

pop bx

pop ax

ret

printNum endp

readNum proc

push bx

push cx

push dx

push si

push di

push bp

mov si, offset inbuf

mov ax,0a00h

mov dx,si

int 21h

xor cx,cx

inc si

mov cl,byte ptr [si]

jcxz convert_word_err

add si,cx

mov ax,1

mov bp,10

xor bx,bx

mov di,ax

make_word:

mov dl,byte ptr [si]

cmp dl,'0'

jb convert_word_err

cmp dl,'9'

ja convert_word_err

and dx,000fh

mul dx

test dx,dx

jnz convert_word_err

add bx, ax

jc convert_word_err

mov ax, di

mul bp

mov di,ax

dec si

loop make_word

mov ax,bx

pop bp

pop di

pop si

pop dx

pop cx

pop bx

ret

convert_word_err:

mov ax,0900h

mov dx,offset mesError

int 21h

mov ax,0700h

int 21h

mov ax,4c00h

int 21h

readNum endp

inputLim proc

mov ax,0900h

mov dx, offset limInput

int 21h

call readNum

mov left,al

call readNum

mov right,al

ret

inputLim endp

inputMas proc

mov ax,0900h

mov dx, offset massInput

int 21h

mov cx,mas_num

mov bx,0

next_el:

call readNum

mov mass[bx],al

mov ax,0900h

mov dx, offset ent

int 21h

add bx,1

loop next_el

ret

inputMas endp

counting proc

mov cx, mas_num

mov bx, 0

mov al, 0

cmp_lim:

mov dl, left

cmp mass[bx], dl

jge test2

add bx, 1

mov count, al

loop cmp_lim

jmp end

test2:

mov dl, right

cmp mass[bx], dl

jle plus

add bx, 1

mov count, al

loop cmp_lim

plus:

add al, 1

add bx, 1

mov count, al

loop cmp_lim

end:

ret

counting endp

start:

mov ax,@data

mov ds,ax

call inputMas

call inputLim

call counting

mov ax,0900h

mov dx, offset doneMess

int 21h

mov al,count

call printNum

end start

59. Арифметические операции со знаковыми и беззнаковыми числами.

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

Команда сложения с переносом ADC – это та же команда ADD, за исключением того, что в сумму включается флаг переноса CF, который прибавляется к младшему биту результата.

Команда вычитания SUB – идентична команде сложения, за исключением того, что она выполняет вычитание, а не сложение.

Команда вычитания с заемом SBB учитывает флаг заема CF, то есть значение заема вычитается из младшего бита результата.

Команда отрицания NEG – оператор смены знака. Она меняет знак двоичного кода операнда – байта или слова.

Команды инкремента и декремента изменяют значение своего единственного операнда на единицу. Команда INC прибавляет 1 к операнду, а команда DEC вычитает 1 из операнда. Обе команды могут работать с байтами или со словами. На флаги команды влияния не оказывают.

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

Cуществуют две формы деления – одна для двоичных чисел без знака DIV, а вторая для чисел со знаком – IDIV. Любая форма деления может работать с байтами и словами. Один из операндов (делимое) всегда в два раза длиннее обычного операнда.

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