
- •Утверждаю
- •Системное программирование
- •Содержание
- •Пояснительная записка
- •Тематический план
- •Методические рекомендации по изучению тем дисциплины
- •Раздел 1. Системы программирования.
- •Раздел 2. Основы программирования на языке ассемблера.
- •Методические рекомендации по оформлению и выполнению домашней контрольной работы
- •Критерии оценки домашней контрольной работы
- •Теоретические сведения
- •Команды работы с адресами и указателями памяти
- •ПримерЫ решения задач
- •Раздел 1 Системы программирования
- •Раздел 2 Основы программирования на языке ассемблера.
- •Литература Основная
- •Дополнительная
ПримерЫ решения задач
№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
ПРИМЕРНЫЙ ПЕРЕЧЕНЬ ТЕОРЕТИЧЕСКИХ ВОПРОСОВ К ЭКЗАМЕНУ