Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_СПРГ_зо_без заданий.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
701.95 Кб
Скачать

ПримерЫ решения задач

1 (линейная программа, пример выполнения задания 1):

Записать в ячейки памяти числа 24h и a7h, перемножить их, найти дополнительный код, вычесть b734h. Окончательный результат записать в ячейку памяти.

Исходный текст программы для получения .com

prg segment para public 'code' ;описание сегмента

assume cs:prg,ss:prg,es:prg,ds:prg ;все сегментные регистры привязаны к одному сегменту

org 100h ;начальное смещение программы

start: jmp go ;начальная метка программы

c1 db 24h ;резервирование ячейки памяти для записи первого числа

c2 db 0a7h ;резервирование ячейки памяти для записи второго числа

c3 dw ? ;резервирование ячеек памяти для записи результата

go:

mov al,c1 ;запись в al первого числа

mov ah,0 ;очистка ah

mul c2 ;перемножение чисел

neg ax ;получение дополнительного кода

sub ax,0b734h ;вычитание из результата числа

mov c3,ax ;запись результата в память

ret

prg ends ; конец сегмента

end start ; конец программы

и .exe файла

model small ; директива модели памяти

.stack 100h ;сегмент стека и его размер

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

c1 db 24h ;ячейка памяти с1

c2 db 0a7h ;ячейка памяти с2

c3 dw ? ; ячейка памяти для результата

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

start: ;начальная метка программы

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

mov ds,ax ;запись в ds адреса сегмента данных

xor ax,ax ;очистка ax

mov al,c1 ;запись в al первого числа

mul c2 ;перемножение чисел

neg ax ;получение дополнительного кода

sub ax,0b734h ;вычитание

mov c3,ax ;запись результата в память

mov ax,4c00h ;стандартный выход из программы

int 21h

end start

2 Вычислить значение y = (a + b)/c, где a, b, c – байтовые знаковые переменные.

Исходный текст программы для получения .exe

model small

.stack 256

.data

a db ?

b db ?

c db ?

y dw 0

.code

main: ;точка входа в программу

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

mov ds,ax ; запись в ds адреса сегмента данных

xor ax,ax ; очистка ax

mov al,a

mov bl,b

add al,bl

idiv c ; в al — частное, в ah — остаток

mov y,ax

mov ax,4c00h ; стандартный выход

int 21h

end main ; конец программы

и .com файла

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h

start: jmp go

a db ?

b db ?

c db ?

y dw 0

go:

xor ax,ax ;очистка ax

mov al,a

mov bl,b

add al,bl

idiv c ; в al – частное, в ah – остаток

mov y,ax

ret

prg ends

end start

3 В ячейки памяти записать числа E22A и 2В54. Сложить эти числа, в полученном результате маскировать 0-ем 4,7,9,11 и 13-ый разряды. Если окончательный результат меньше AD47, то в регистр CL записать 4F, а иначе в этот же регистр записать 1F.

Исходный текст программы для получения .com

prg segment para public 'code' ;описание сегмента

assume cs:prg,ss:prg,es:prg,ds:prg ;все сегментные регистры привязаны к одному сегменту prg

org 100h ;начальное смещение программы

start: jmp go ;начальная метка программы

a dw 0E22Ah ; ячейка для записи первого числа

b dw 2B54h ; ячейка для записи второго числа

go:

mov ax,a ;запись в ax первого числа

add ax,b ;cложение чисел

and ax,0D56Fh ;маскирование 0-ем

cmp ax,0AD47h;сравнение результата с AD47

jb m ;переход на метку m, если результат меньше

mov cl,1F ;запись в CL признака больше или равно

jmp m1 ;переход на конец программы

m: mov cl,4F ;запись в СL признака меньше

m1: ret

prg ends ;конец сегмента

end start ;конец программы

и .exe файла

model small ;директива модели памяти

.stack 100h ;сегмент стека и его размер

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

a dw 0E22Ah

b dw 2B54h

start: mov ax,@data

mov ds,ax

xor ax,ax

mov ax,a

add ax,b ;сложение чисел

and ax,0D47h ;маскирование 0-ем

cmp ax,0Ad47h ;сравнение

jb m

mov cl,1Fh ;запись в CL признака ≥

jmp m1 ;переход на стандартный выход

m: mov cl,4Fh

mov ch3,ax ;запись результата в память

m1: mov ax,4c00h ;стандартный выход из

int 21h

end start программы

4 (система уравнений, пример выполнения задания 2):

prg segment para public ‘code’

assume ds:prg,cs:prg,ss:prg

org 100h

start: jmp go

x db ?

y db ?

z db ?

go:

cmp x,5

jle m

cmp x,8

jle m1

mov al,3

mul y; 3у

mov bl,al

mov al,x

mul al; х2

mov bl,2

mul bl; 2х2

sub al,bl

jmp m2

m: mov al,y

mul al; у2

mov bl,al

mov al,x

mul al

mul x; х3

sub al,bl

jmp m2

m1: mov al,x

mov bl,5

div bl

mov bl,al

mov al,2

mul x

mul y

add al,bl

m2: mov z,al

ret

prg ends

end start

5 (линейные массивы, пример выполнения задания 3):

Дан массив из 15 байт. Подсчитать сколько в данном массиве положительных элементов.

1 способ

model small ;директива модели памяти

.stack 100h ;сегмент стека и его размер

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

mas db 21h,0a2h,33h,91h,11h,45h,73h,82h,0e1h,65h,44h,88h,0dah,34h,93h

kol db ?

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

start: ;начальная метка программы start

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

mov ds,ax ;запись в ds адреса сегмента данных

xor ax,ax ;очистка ax

mov si,0 ;запись в si индекса первого элемента

mov cx,15 ;запись в счетчик количества элементов

m1: add mas[si],0 ;установка флажков

js m ;переход, если число отрицательное

inc kol ;подсчет положительных чисел

m: inc si ;получение индекса следующего элемента

loop m1 ;уменьшение количества циклов на 1 и переход на начало цикла, если CX<>0

mov ax,4c00h ;стандартный выход из программы

int 21h

end start

2 способ

m1:

cmp mas[si],0 ;сравнение элемента массива с нулем

jle m ;переход, если число отрицательное

inc kol

6 (матрица, пример решения задания 4):

Дан прямоугольный массив 5*2. Подсчитать сколько в данном массиве элементов равных 3.

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h

start: jmp go

mas dw 1,2,3,4,5,6,7,3,9,3

elem dw 3

kol db ?

s1 db 0ah,0dh,’нет такого элемента$’

s2 db 0ah,0dh,’количество найденных элементов равных 3 =$’

go: mov bx,0 ;запись в bx начального индекса строки

mov cx,5 ;запись в cx количество строк (внешних циклов)

m2: push cx ;сохраняем количество внешних циклов в стеке

mov si,0 ;запись в si индекса начального столбца

mov cx,2 ;запись в счетчик количества столбцов (внутренних циклов)

m1: mov ax, mas[bx][si] ;запись в ax элемента массива

cmp ax,elem

jne m ;переход, если число не равно 3

inc kol ;подсчет чисел равных 3

m: inc si ;получение индекса следующего элемента (т.к. массив слов SI увеличиваем на 2)

inc si

loop m1 ;уменьшение количества циклов на 1 и переход на начало цикла, если CX<>0

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

add bx,4 ;получаем адрес следующей строки

loop m2 ;переход, если количество внешних циклов не равно нулю

cmp kol,0 ;сравнение полученного количества с нулем

je m3 ;переход, если полученное количество равно нулю

lea dx,s2 ;запись в dx адреса строки s2

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

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

m ov dl,kol ;вывод значения переменной kol на экран

add dl,30h

mov ah,02h ;запись функции вывода числа на экран

int 21h

jmp m4 ;переход на выход с программы

m3: lea dx,s1 ;запись в dx адреса строки s1

mov ah,09h ;запись функции вывода строки s1

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

m4: ret

prg ends ;конец сегмента

end start ;конец программы

7 (строки, пример выполнения задания 5):

Сравнить элементы двух строк и выдать сообщение совпадают символы строк или нет.

Исходный текст программы для получения .соm

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h ; начальное смещение программы

start: jmp go ; начальная метка программы

str1 db 0ah,0dh,'строки совпадают$'

str2 db 0ah,0dh,'строки не совпадают$'

src db 0ah,0dh,'0123456789$' ; 1-ая строка

dst db 0ah,0dh,'0023456789','$' ; 2-ая строка

go:

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

lea dx,src ; запись адреса 1-ой строки

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

lea dx,dst ;запись адреса 2-ой строки

int 21h

cld ;установка флажка DF

lea si,src ;запись в SI адреса 1-ой строки

lea di,dst ;запись в DI адреса 2-ой строки

mov cx,10 ; счетчик

repe cmpsb сравнение символов строк

jcxz m ;сх=0, строки совпадают

jne m1; если не равны - переход на метку m1

m: mov ah,09h ;вывод на экран STR1

lea dx,str1

int 21h

jmp z

m1: mov ah,09h ;вывод на экран STR2

lea dx,str2

int 21h

z: ret

prg ends ;конец сегмента

end start ;конец программы

и .ехе файла

model small ; директива модели памяти

.stack 100h ; сегмент стека и его размер

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

strl db 0ah,0dh,'cтpoки совпадают$'

str2 db 0ah,0dh,'cтрoки не совпадают$’

src db '01234567890',0ah,0dh,'$'

dst db '0123456789','$'

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

start: mov ax,@data

mov ds,ax

mov es,ax

xor ax,ax

mov ah,09h

lea dx,src

int 21h ;функция прерывания

lea dx,dst

int 21h

cld

lea si,src ;запись в SI адреса 1-ои строки

lea di,dst ;запись в DI адреса 2-ой строки

mov сх,10

гере cmpsb

jcxz m

jne m1; если не равны - переход на метку m1

m: mov ah,09h ; вывод на экран STR2

lea dx,strl

int 21h

jmp z ;переход на выход из программы

m1: mov ah,09h ;вывод на экран STR1

lea dx,str2

int 21h

z: mov ax,4c00h

int 21h

end start

8 (строки, пример выполнения задания 5):

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

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h

start: jmp go

s db 'sipsokp$'

go: mov cx,7

lea di,s

cld

mov al,'p'

repne scasb

inc cx

mov dl,7

sub dl,cl

add dl,30h

mov ah,02h

int 21h

ret

prg ends

end start

9 (структуры, пример выполнения задания 6):

Дан массив структур. Выдать на экран всех сотрудников отдела мужского пола.

Примечание: для корректного вывода на экран значение полей набирать на анг. яз.

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h

start: jmp go

worker struc

fio db 30 dup(' ')

sex db ' '

razriad db ?

worker ends

mas worker <'Гурко Иван Иванович$','м',3>,<'Сидоров Иван Петрович$','м',2>,<'Муха

Василий Васильевич$','м',4>,<'Петрова Алла Борисовна$','ж',6>,<'Иванова Мария Ивановна$','ж',6>

go: lea di,mas

mov cx,5

mov bl,'м'

m: cmp [di].sex,bl

jne m1

lea dx,[di].fio

mov ah,09h

int 21h

m1: add di,type worker

loop m

ret

prg ends

end start

10 (процедуры, пример решения задания 7):

Дан массив 3*3. Определить сумму элементов каждой строки в процедуре.

Model small

.stack 100h

.data

mas db 1,2,3,0,1,2,2,3,4

string db 0ah,0dh,'сумма строки','$'

.code

summa proc

mov si,0

mov cx,3

m: add al,mas[bx][si]

inc si

loop m

mov dl,al

mov ah,02h

add dl,30h

int 21h

ret

summa endp

start:

mov ax,@data

mov ds,ax

xor ax,ax

mov bx,0

mov cx,3

m1: lea dx,string

mov ah,09h

int 21h

push cx

xor ax,ax

call summa

pop cx

add bx,3

loop m1

mov ax,4c00h

int 21h

end start

11 (макроопределения, пример выполнения задания 8):

Из 4-ех чисел а, d, с и d определить максимальное.

Model small

max macro rg1,rg2

local m1, m

cmp rg1,rg2

ja m

mov al,rg2

jmp m1

m: mov al,rg1

m1: endm

.stack 100h

.data

a db 3

b db 5

c db 9

d db 8

.code

start: mov ax,@data

mov ds,ax

mov es,ax

xor ax,ax

mov bl,a

mov dl,b

max bl,dl

mov dl,al

mov bl,c

max bl,dl

mov dl,al

mov bl,d

max bl,dl

mov ah,0eh

add al,30h

int 10h

mov ax,4c00h

int 21h

end start

Даны массивы М1 и М2 по 10 байт каждый. Получить из них массив М3, состоящий из 9 байт, каждый элемент которого равен сумме целых частей частного двух соседних элементов массивов М1 и М2, т.е. М3=INT (M1(I)/M1(I+1))+INT(M2(I)/M2(I+1)).

assume cs:code,ds:code

code segment

org 100h

m1 db 9,8,6,2,3,2,1,1,6,2

m2 db 9,7,6,3,4,3,2,1,2,1

m3 db 9 dup(?)

divm macro oper1, oper2, rez

push ax

push bx

mov ah,00

mov al,oper1

mov bl,oper2

idiv bl

mov rez,al

pop bx

pop ax

endm

start: mov ax, code

mov ds,ax

lea si,m1

lea di,m2

mov bx,0

mov cx,9

pov: divm [si],[si+1],dh

divm [di],[di+1],dl

add dh,dl

mov m3[bx],dh

inc si

inc di

inc bx

loop pov

int 3

code ends

end start Ответ: массив m3 – 225023305

Даны 3 числа X,Y,Z (байты). Если X<Y, то в число К записать 99, иначе 00; сравнивает Y и Z, если Y<Z, то в число К1 записать 99, иначе 00. Процесс сравнения операндов осуществляется в макроопределении SRAV.

assume cs:code,ds:code

code segment

org 100h

x db 01

y db 02

z db 08

k db ?

k1 db ?

spravn macro oper1,oper2,rez

local men2,stop

push ax

push bx

mov bh,oper2

cmp oper1,bh

jb men2

mov ah,00

jmp stop

men2: mov ah,99h

stop: mov rez,ah

pop bx

pop ax

endm

start: mov ax,code

mov ds,ax

spravn x,y,k

spravn y,z,k1

int 3

code ends

end start

12 (макроопределения, пример выполнения задания 8):

Дан массив N, состоящий из 10 байт. Умножить каждый элемент на 9.

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h

umnojenie macro R

mul n[R]

endm

start: jmp go

N db 1,2,3,4,5,6,7,1,2,3

go: mov si,0

mov cx,10

m: xor ax,ax

mov al,9

umnojenie si

mov N[si],al

inc si

loop m

ret

prg ends

end start

13 (ввод/вывод информации, пример выполнения задания 9):

Ввод строки с использованием функции BIOS 10h

model small

.stack 100h

.data

string db 5 dup(' '),'$'

.code

start:

mov ax,@data

mov ds,ax

xor ax,ax

mov cx,5 ;запись количества символов

lea di,string ;запись адреса начала строки

m1: mov ah,01h

int 21h

stosb ;запись символов из аккумулятора в строку

loop m1

lea dx,string

mov ah,09h

int 21h

mov ax,4c00h

int 21h

end start

Вывод строки с помощью функции BIOS 13h

model small

.stack 100h

.data

string db "stroka$"

.code

start: mov ax,@data

mov ds,ax

mov es,ax

xor ax,ax

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

mov al,01h;после вывода курсор в конце строки

xor bh,bh ;номер видеостраницы

mov bl,7 ;атрибут

mov dh,3 ;строка начала вывода

mov dl,3 ;столбец начала вывода

lea bp,string ;запись адреса строки

mov ah,13h

int 10h

mov ax,4c00h

int 21h

end start

14 (пример выполнения задания 9): Ввести строку из 10 символов. Если количество символов “В“ в ней больше половины, выдать сообщение “В строке символов В больше 5“, иначе сообщение “В строке символов В меньше 5“.

prg segment para public 'code'

assume cs:prg,ss:prg,es:prg,ds:prg

org 100h

start: jmp go

s db 10 dup (' '),'$'

s1 db 'В строке символов В больше 5$'

s2 db 'В строке символов В меньше 5$'

kol db ?

go: mov cx,10

lea di,s

n: mov ah,01h

int 21h

stosb; ввод строки с клавиатуры

loop n

mov cx,10

lea di,s

mov al,'b'

z: scasb

jne m

inc kol; количество символов b

m: loop z

cmp kol,5

ja x

lea dx,s2

jmp y

x: lea dx,s1

y: mov ah,09h

int 21h

ret

prg ends

end start

15 (пример выполнения задания 10):

Просуммировать две переменные х, у

Var

Переслать символы

одной строки в другую

Var n:integer;

Уменьшить каждый элемент массива в 2 раза

Var i:byte;

a:array[1..10] of byte;

x,y,z:integer;

begin

writeln('x,y');

readln(x,y);

st1,st2:string;

begin writeln('st1');

readln(st1);

n:=length(st1);

begin writeln('enter mas');

for i:=1 to 10 do readln(a[i]);

ASM

push ds

ASM

mov ax,x

add ax,y

mov z,ax

END;

writeln(z);

end.

ASM

push ds

mov ax,seg st1

mov ds,ax

mov es,ax

lea si,st1

lea di,st2

inc n

mov cx,n

rep movsb

pop ds

END;

writeln(st2);

end.

mov ax,seg a

mov ds,ax

lea si,a

mov cx,10

mov bl,2

@m: xor ax,ax

mov al,[si]

div bl

mov [si],ah

inc si

loop @m

pop ds

END;

for i:=1 to 10 do write(a[i],' ');

end.

Подсчет символов а в строке

#include<stdio.h>

void main()

{ char s[10];

int k=0;

puts("s");

gets(s);

asm {

lea di,s

mov al,'a'

mov cx,10 }

m1: asm { scasb

jne m

inc k }

m: asm { loop m1 }

printf("%d",k); }

Подсчет суммы элементов массива

#include"stdio.h"

void main()

{ int a[10];

int i,s=0;

puts("enter massiv");

for(i=0;i<10;i++)

scanf("%d",&a[i]);

asm {

lea si,a

mov cx,10

xor ax,ax }

m: asm { add ax,[si]

add si,2

loop m }

printf("%d",_AX); }

Пересылка символов одной строке во вторую

#include<stdio.h>

void main()

{ char s2[10]=" ",s1[10];

puts("S1");

gets(s1);

asm {

lea si,s1

lea di,s2

mov cx,10

rep movsb

}

puts(s2);

}

Подсчет суммы элементов массива

#include"stdio.h"

extern "C" int summa(int *mas);

void main()

{ int m[10],s=0,i;

puts("enter massiv");

for(i=0;i<10;i++)

scanf("%d",&m[i]);

s=summa(m);

printf("%d",s); }

Количество равных соответствующих символов

model small

.stack 100h

model small

.stack 100h

public _summa

.code

_summa proc c near adr_mas:word

xor ax,ax

mov si,adr_mas

mov cx,10

m: add ax,[si]

add si,2

loop m

ret

_summa endp

end

.code

public _kol

_kol proc с near s1:word,s2:word,d:word

mov ax,ds

mov es,ax

mov ax,0

mov d,0

mov cx,10

lea si,s1

lea di,s2

m: mov al,[si]

cmp al,[di]

jnz m1

inc d

m1: inc si

inc di

loop m

mov ax,d

ret

_kol endp

end

#include"stdio.h"

extern "C" int kol(char *s1,char *s2,int d);

void main()

{

char st1[10],st2[10];

int k=0,c;

scanf("%s %s",st1,st2);

c=kol(st1,st2,k);

printf("%d",c);

}

16. Дан файл. Подсчитать, сколько слов содержит данный файл.

prg segment para public 'code'

assume cs:prg,ds:prg,ss:prg,es:prg

org 100h

start: jmp go

nam db 'text.txt',0

desc dw ?

buffer db 50 dup(?)

mes db 'error$'

kol db ?

go: lea dx,nam ;открытие файла

mov ah,3dh

int 21h

jc m

mov desc,ax

m3: mov bx,desc ; чтение по одному символу из файла

mov ah,3fh

mov cx,1

lea dx,buffer

int 21h

jc m

cmp ax,0 ; признак конца файла

je m1

mov al,' '

lea di,buffer

scasb ; сравнение считываемого символа с пробелом

jne m2

inc kol ; подсчет пробелов

m2: jmp m3

m1: mov ah,02h ;выдача на экран количества слов

add kol,31h

mov dl,kol

int 21h

jmp m4

m: lea dx,mes ; выдача ошибки при работе с файлом

mov ah,09h

int 21h

m4: ret

prg ends

end start

ПРИМЕРНЫЙ ПЕРЕЧЕНЬ ТЕОРЕТИЧЕСКИХ ВОПРОСОВ К ЭКЗАМЕНУ