Добавил:
БГУИР ПОИТ Дистанционное Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Часть 1 / КР1_В5 / Отчет КР1

.docx
Скачиваний:
13
Добавлен:
06.10.2021
Размер:
65.56 Кб
Скачать

БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ

Кафедра программного обеспечения информационных технологий

Факультет ФКСиС

Специальность ПОИТ

Контрольная работа №1

по дисциплине «Языки программирования часть 1»

Вариант 5

Выполнил студент: Бордон Е.С.

группа 991051

Зачетная книжка № 99105004

Минск 2021

Условия задачи

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

Программа 1. Передача параметров через регистр. Тип процедуры – дальний.

Программа 2. Передача параметров через глобальные переменные. Тип процедуры – дальний.

Программа 3. Передача параметров через стек. Тип процедуры – ближний.

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

Ввести два 16-битовых целых числа А и В. Вычислить значение

выражения: A/B – 7*B.

Пояснения к работе программы

Программы написаны на Assembler для MASM для выполнения на современных 32-битных процессорах в ОС Windows с использованием среды разработки SASM и отладчика OllyDbg.

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

Результат работы программы

Рис 1. Результат работы программы

Тестовый набор данных:

Программа 1

A

B

A/B – 7*B

990

851

-5955,84

205

956

-6691,79

213

19

-121,79

45

2

8,50

403

515

-3604,22

0

3

-21,00

7

7

-48,00

Программа 2

A

B

A/B – 7*B

990

851

-5955,84

205

956

-6691,79

213

19

-121,79

45

2

8,50

403

515

-3604,22

0

3

-21,00

7

7

-48,00

Программа 3

A

B

A/B – 7*B

990

851

-5955,84

205

956

-6691,79

213

19

-121,79

45

2

8,50

403

515

-3604,22

0

3

-21,00

7

7

-48,00

Листинг программы 1

.386 ; код скомпилируется для сравнительно современных 32-битных процессоров

.model flat, stdcall ; устанавливаем модель памяти windows, очистку стека осуществляет вызываемая подпрограмма

option casemap : none ; делаем переменные регистрозависимыми

include \masm32\include\kernel32.inc ; для использования базового API Windows

include \masm32\include\msvcrt.inc ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib ; для использования базового API Windows

includelib \masm32\lib\msvcrt.lib ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

BSIZE equ 20 ; буффер для вывода 64-битных чисел

CRLF equ 13, 10 ; синоним перевода строки в консоли

.data

; далее переменные с фрагментами текста для общения с пользователем

msgInputA db "Enter decimal integer number A from 0 to 65535:", CRLF, 0 ; текст приглашения указать первое число

msgInputB db "Enter decimal integer number B from 0 to 65535:", CRLF, 0 ; текст приглашения указать второе число

msgInputY db "*** A/B-7B ***", CRLF, 0 ; условие

msgInputRes db "Result is ", 0

msgInputResm db "Result is -", 0 ; текст вступления перед выводом результата вычислений

msgInputOst db ",00", 0 ; остаток если нет

msgInputOstt db ",", 0 ; если есть остаток

msgFinal db CRLF, "Enter any char and press 'Enter' for exit", CRLF, 0; инструкция по выходу из программы

formatInt db '%d',0 ; описание формата целого числа

formatStr db '%s',0 ; описание формата строки

x db ?

.data?

numA dw ? ; переменная для хранения числа А

numB dw ? ; переменная для хранения числа В

numRes db BSIZE dup (?) ; переменная для хранения результата вычислений в строчном формате - массив из 20 символов по 1 байту

.code

start:

invoke crt_printf, ADDR formatStr, ADDR msgInputA ; выводим приглашение ввести первое число

invoke crt_scanf, ADDR formatInt, ADDR numA ; считываем первое число в переменную numA

xor esi, esi ; обнуляем регистр esi

mov si, numA ; копируем первое число в регистр si для передачи в функцию

invoke crt_printf, ADDR formatStr, ADDR msgInputB ; выводим приглашение ввести второе число

invoke crt_scanf, ADDR formatInt, ADDR numB ; считываем второе число в переменную numB

xor edi, edi ; обнуляем регистр edi

mov di, numB ; копируем первое число в регистр di для передачи в функцию

invoke crt_printf, ADDR formatStr, ADDR msgInputY ; выводим условие

call arifm ; вызываем процедуру-обработчик

invoke crt_printf, ADDR formatStr, ADDR msgFinal ; объясняем, как выйти из программы

invoke crt_scanf, ADDR formatStr, ADDR numA ; переиспользуем переменную для хранения ненужных данных

invoke ExitProcess, 0 ; закрываем программу, возвращаемся к ОС

arifm proc far ; тип вызова процедуры - дальний

;________________________________________________________________________

; a/b-7b

mov eax, esi ; в esi храниться numA

mov edx, 0 ; вводим целые числа

mov ebx, edi ; в edi храниться numB

div ebx ; (dx,ax)/bx = ax, dx **** a/b ****

mov ecx, eax ; результат a/b целая часть

mov eax, 100 ; переводим в десятичный вид для вывода в строку

mul edx

div ebx

mov edi, eax

mov eax, 7

mul ebx ; 7*b результат edx:eax

cmp ecx, eax ; тест на отрицательный результат для вывода в строку

jl min ; <

jg EndPr ; >

jz EndPr ; =

min:

cmp edi, 0

jl EndPr ; <

jg big ; >

jz EndPr ; =

big: ; если есть остаток от деления

add ecx, 1

sub edi, 100

neg edi

JMP EndPr

EndPr:

sub ecx, eax ; от целой части a/b отнимаем целую часть 7*b Ответ ecx

mov eax, ecx ; eax = ответ целая часть

test eax, eax ; тест на знак числа ответа

JZ plus

js minys

plus:

mov x, 0

JMP EndProg

minys:

neg eax ; для перевода в строку

mov x, 1

JMP EndProg

EndProg:

; eax - ответ на поставленную задачу, целая часть

; осталось вывести его на экран, преобразовав в строку с учётом того,

; что число может превышать 32-бита, т.е. стандартные функции с ним работать не могут

; подготовим вспомогательные данные

mov esi, BSIZE ; устанавливаем счётчик цикла равным длине максимального десятичного числа, помещающегося в 64-бита

mov ebx, edx ; копируем в ebx значение edx для дальнейшего оперирования обеими копиями значения

mov ecx, 10 ; для извлечения минимального десятичного числа будем делить на 10

nxt:

dec esi ; позиция следующего символа

xchg eax, ebx ; делим ...

xor edx, edx ; ... старшую ...

div ecx ; половину

xchg eax, ebx ; сохраняем частное

div ecx ; и делим остаток + младшую половину

add dl, 48 ; преобразуем в код соответствующего ASCII-символа

mov numRes[esi], dl ; сохраняем символ в буфер

mov edx, ebx ; возвращаем частное в edx

or edx, eax ; если оба частных равны нулю...

jnz nxt ; пойдём к следующей по порядку инструкции, иначе вернёмся в начало цикла

test x, 1 ; тест на знак числа ответа

jz pls

jnz mns

pls:

invoke crt_printf, ADDR formatStr, ADDR msgInputRes ; текст-пояснение 'Result is'

JMP EProg

mns:

invoke crt_printf, ADDR formatStr, ADDR msgInputResm ; текст-пояснение 'Result is -'

JMP EProg

EProg:

mov edx, offset numRes ; запоминаем адрес начала массива

add edx, esi ; добавляем смещение до первого символа, теперь в edx адрес первого символа строки результата

invoke crt_printf, ADDR formatStr, edx ; выводим результат вычислений на экран (десятичное число) целая часть

; вывод на экран дробной части

cmp edi, 0

jl mesgg ; <

jg mesgg ; >

jz mesg ; =

mesg:

invoke crt_printf, ADDR formatStr, ADDR msgInputOst ; если дробной части нет

JMP EndPrg

mesgg:

mov eax, edi ; если она есть

xor edx, edx

xor esi, esi

xor dl, dl

mov esi, BSIZE ; устанавливаем счётчик цикла равным длине максимального десятичного числа, помещающегося в 64-бита

mov ebx, edx ; копируем в ebx значение edx для дальнейшего оперирования обеими копиями значения

mov ecx, 10 ; для извлечения минимального десятичного числа будем делить на 10

nxtt:

dec esi ; позиция следующего символа

xchg eax, ebx ; делим ...

xor edx, edx ; ... старшую ...

div ecx ; половину

xchg eax, ebx ; сохраняем частное

div ecx ; и делим остаток + младшую половину

add dl, 48 ; преобразуем в код соответствующего ASCII-символа

mov numRes[esi], dl ; сохраняем символ в буфер

mov edx, ebx ; возвращаем частное в edx

or edx, eax ; если оба частных равны нулю...

jnz nxtt ; пойдём к следующей по порядку инструкции, иначе вернёмся в начало цикла

invoke crt_printf, ADDR formatStr, ADDR msgInputOstt ; выводим знак ","

mov edx, offset numRes ; запоминаем адрес начала массива

add edx, esi ; добавляем смещение до первого символа, теперь в edx адрес первого символа строки результата

invoke crt_printf, ADDR formatStr, edx ; выводим само число

JMP EndPrg

EndPrg:

ret ; возврат управления вызвавшей программе

arifm endp ; конец процедуры arifm

end start ; выполнение программы начнётся с метки start

Листинг программы 2

.386 ; код скомпилируется для сравнительно современных 32-битных процессоров

.model flat, stdcall ; устанавливаем модель памяти windows, очистку стека осуществляет вызываемая подпрограмма

option casemap : none ; делаем переменные регистрозависимыми

include \masm32\include\kernel32.inc ; для использования базового API Windows

include \masm32\include\msvcrt.inc ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib ; для использования базового API Windows

includelib \masm32\lib\msvcrt.lib ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

BSIZE equ 20 ; буффер для вывода 64-битных чисел

CRLF equ 13, 10 ; синоним перевода строки в консоли

.data

; далее переменные с фрагментами текста для общения с пользователем

msgInputA db "Enter decimal integer number A from 0 to 65535:", CRLF, 0 ; текст приглашения указать первое число

msgInputB db "Enter decimal integer number B from 0 to 65535:", CRLF, 0 ; текст приглашения указать второе число

msgInputY db "*** A/B-7B ***", CRLF, 0 ; условие

msgInputRes db "Result is ", 0

msgInputResm db "Result is -", 0 ; текст вступления перед выводом результата вычислений

msgInputOst db ",00", 0 ; остаток если нет

msgInputOstt db ",", 0 ; если есть остаток

msgFinal db CRLF, "Enter any char and press 'Enter' for exit", CRLF, 0; инструкция по выходу из программы

formatInt db '%d',0 ; описание формата целого числа

formatStr db '%s',0 ; описание формата строки

x db ?

.data?

numA dw ? ; переменная для хранения числа А

numB dw ? ; переменная для хранения числа В

numRes db BSIZE dup (?) ; переменная для хранения результата вычислений в строчном формате - массив из 20 символов по 1 байту

.code

start:

invoke crt_printf, ADDR formatStr, ADDR msgInputA ; выводим приглашение ввести первое число

invoke crt_scanf, ADDR formatInt, ADDR numA ; считываем первое число в переменную numA

invoke crt_printf, ADDR formatStr, ADDR msgInputB ; выводим приглашение ввести второе число

invoke crt_scanf, ADDR formatInt, ADDR numB ; считываем второе число в переменную numB

invoke crt_printf, ADDR formatStr, ADDR msgInputY ; выводим условие

call arifm ; вызываем процедуру-обработчик

invoke crt_printf, ADDR formatStr, ADDR msgFinal ; объясняем, как выйти из программы

invoke crt_scanf, ADDR formatStr, ADDR numA ; переиспользуем переменную для хранения ненужных данных

invoke ExitProcess, 0 ; закрываем программу, возвращаемся к ОС

arifm proc far ; тип вызова процедуры - дальний

;________________________________________________________________________

; a/b-7b

mov eax, 1

mul numA

mov edx, 0 ; вводим целые числа

div numB ; (dx,ax)/bx = ax, dx **** a/b ****

mov ecx, eax ; результат a/b целая часть

mov eax, 100 ; переводим в десятичный вид для вывода в строку

mul edx

div numB

mov edi, eax

mov eax, 7

mul numB ; 7*b результат edx:eax

cmp ecx, eax ; тест на отрицательный результат для вывода в строку

jl min ; <

jg EndPr ; >

jz EndPr ; =

min:

cmp edi, 0

jl EndPr ; <

jg big ; >

jz EndPr ; =

big: ; если есть остаток от деления

add ecx, 1

sub edi, 100

neg edi

JMP EndPr

EndPr:

sub ecx, eax ; от целой части a/b отнимаем целую часть 7*b Ответ ecx

mov eax, ecx ; eax = ответ целая часть

test eax, eax ; тест на знак числа ответа

JZ plus

js minys

plus:

mov x, 0

JMP EndProg

minys:

neg eax ; для перевода в строку

mov x, 1

JMP EndProg

EndProg:

; eax - ответ на поставленную задачу, целая часть

; осталось вывести его на экран, преобразовав в строку с учётом того,

; что число может превышать 32-бита, т.е. стандартные функции с ним работать не могут

; подготовим вспомогательные данные

mov esi, BSIZE ; устанавливаем счётчик цикла равным длине максимального десятичного числа, помещающегося в 64-бита

mov ebx, edx ; копируем в ebx значение edx для дальнейшего оперирования обеими копиями значения

mov ecx, 10 ; для извлечения минимального десятичного числа будем делить на 10

nxt:

dec esi ; позиция следующего символа

xchg eax, ebx ; делим ...

xor edx, edx ; ... старшую ...

div ecx ; половину

xchg eax, ebx ; сохраняем частное

div ecx ; и делим остаток + младшую половину

add dl, 48 ; преобразуем в код соответствующего ASCII-символа

mov numRes[esi], dl ; сохраняем символ в буфер

mov edx, ebx ; возвращаем частное в edx

or edx, eax ; если оба частных равны нулю...

jnz nxt ; пойдём к следующей по порядку инструкции, иначе вернёмся в начало цикла

test x, 1 ; тест на знак числа ответа

jz pls

jnz mns

pls:

invoke crt_printf, ADDR formatStr, ADDR msgInputRes ; текст-пояснение 'Result is'

JMP EProg

mns:

invoke crt_printf, ADDR formatStr, ADDR msgInputResm ; текст-пояснение 'Result is -'

JMP EProg

EProg:

mov edx, offset numRes ; запоминаем адрес начала массива

add edx, esi ; добавляем смещение до первого символа, теперь в edx адрес первого символа строки результата

invoke crt_printf, ADDR formatStr, edx ; выводим результат вычислений на экран (десятичное число) целая часть

; вывод на экран дробной части

cmp edi, 0

jl mesgg ; <

jg mesgg ; >

jz mesg ; =

mesg:

invoke crt_printf, ADDR formatStr, ADDR msgInputOst ; если дробной части нет

JMP EndPrg

mesgg:

mov eax, edi ; если она есть

xor edx, edx

xor esi, esi

xor dl, dl

mov esi, BSIZE ; устанавливаем счётчик цикла равным длине максимального десятичного числа, помещающегося в 64-бита

mov ebx, edx ; копируем в ebx значение edx для дальнейшего оперирования обеими копиями значения

mov ecx, 10 ; для извлечения минимального десятичного числа будем делить на 10

nxtt:

dec esi ; позиция следующего символа

xchg eax, ebx ; делим ...

xor edx, edx ; ... старшую ...

div ecx ; половину

xchg eax, ebx ; сохраняем частное

div ecx ; и делим остаток + младшую половину

add dl, 48 ; преобразуем в код соответствующего ASCII-символа

mov numRes[esi], dl ; сохраняем символ в буфер

mov edx, ebx ; возвращаем частное в edx

or edx, eax ; если оба частных равны нулю...

jnz nxtt ; пойдём к следующей по порядку инструкции, иначе вернёмся в начало цикла

invoke crt_printf, ADDR formatStr, ADDR msgInputOstt ; выводим знак ","

mov edx, offset numRes ; запоминаем адрес начала массива

add edx, esi ; добавляем смещение до первого символа, теперь в edx адрес первого символа строки результата

invoke crt_printf, ADDR formatStr, edx ; выводим само число

JMP EndPrg

EndPrg:

ret ; возврат управления вызвавшей программе

arifm endp ; конец процедуры arifm

end start ; выполнение программы начнётся с метки start

Листинг программы 3

.386 ; код скомпилируется для сравнительно современных 32-битных процессоров

.model flat, stdcall ; устанавливаем модель памяти windows, очистку стека осуществляет вызываемая подпрограмма

option casemap : none ; делаем переменные регистрозависимыми

include \masm32\include\kernel32.inc ; для использования базового API Windows

include \masm32\include\msvcrt.inc ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib ; для использования базового API Windows

includelib \masm32\lib\msvcrt.lib ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

BSIZE equ 20 ; буффер для вывода 64-битных чисел

CRLF equ 13, 10 ; синоним перевода строки в консоли

.data

; далее переменные с фрагментами текста для общения с пользователем

msgInputA db "Enter decimal integer number A from 0 to 65535:", CRLF, 0 ; текст приглашения указать первое число

msgInputB db "Enter decimal integer number B from 0 to 65535:", CRLF, 0 ; текст приглашения указать второе число

msgInputY db "*** A/B-7B ***", CRLF, 0 ; условие

msgInputRes db "Result is ", 0

msgInputResm db "Result is -", 0 ; текст вступления перед выводом результата вычислений

msgInputOst db ",00", 0 ; остаток если нет

msgInputOstt db ",", 0 ; если есть остаток

msgFinal db CRLF, "Enter any char and press 'Enter' for exit", CRLF, 0; инструкция по выходу из программы

formatInt db '%d',0 ; описание формата целого числа

formatStr db '%s',0 ; описание формата строки

x db ?

.data?

numA dw ? ; переменная для хранения числа А

numB dw ? ; переменная для хранения числа В

numRes db BSIZE dup (?) ; переменная для хранения результата вычислений в строчном формате - массив из 20 символов по 1 байту

.code

start:

invoke crt_printf, ADDR formatStr, ADDR msgInputA ; выводим приглашение ввести первое число

invoke crt_scanf, ADDR formatInt, ADDR numA ; считываем первое число в переменную numA

push numA

invoke crt_printf, ADDR formatStr, ADDR msgInputB ; выводим приглашение ввести второе число

invoke crt_scanf, ADDR formatInt, ADDR numB ; считываем второе число в переменную numB

push numB

invoke crt_printf, ADDR formatStr, ADDR msgInputY ; выводим условие

call arifm ; вызываем процедуру-обработчик

invoke crt_printf, ADDR formatStr, ADDR msgFinal ; объясняем, как выйти из программы

invoke crt_scanf, ADDR formatStr, ADDR numA ; переиспользуем переменную для хранения ненужных данных

invoke ExitProcess, 0 ; закрываем программу, возвращаемся к ОС

arifm proc near ; тип вызова процедуры - ближний

;________________________________________________________________________

; a/b-7b

mov ebp, esp ; так как регистр esp не может использоваться для косвенной адресации, то вместо esp используется ebp

mov si, [ebp + 6] ; заносим в esi значение из стека с учётом того, что на вершине стека адрес возврата и numB

mov eax, 1

mul si

mov si, [ebp + 4] ; заносим в esi значение из стека с учётом того, что на вершине стека адрес возврата

mov edx, 0 ; вводим целые числа

div si ; (dx,ax)/bx = ax, dx **** a/b ****

mov ecx, eax ; результат a/b целая часть

mov eax, 100 ; переводим в десятичный вид для вывода в строку

mul edx

div si

mov edi, eax

mov eax, 7

mul si ; 7*b результат edx:eax

cmp ecx, eax ; тест на отрицательный результат для вывода в строку

jl min ; <

jg EndPr ; >

jz EndPr ; =

min:

cmp edi, 0

jl EndPr ; <

jg big ; >

jz EndPr ; =

big: ; если есть остаток от деления

add ecx, 1

sub edi, 100

neg edi

JMP EndPr

EndPr:

sub ecx, eax ; от целой части a/b отнимаем целую часть 7*b Ответ ecx

mov eax, ecx ; eax = ответ целая часть

test eax, eax ; тест на знак числа ответа

JZ plus

js minys

plus:

mov x, 0

JMP EndProg

minys:

neg eax ; для перевода в строку

mov x, 1

JMP EndProg

EndProg:

; eax - ответ на поставленную задачу, целая часть

; осталось вывести его на экран, преобразовав в строку с учётом того,

; что число может превышать 32-бита, т.е. стандартные функции с ним работать не могут

; подготовим вспомогательные данные

mov esi, BSIZE ; устанавливаем счётчик цикла равным длине максимального десятичного числа, помещающегося в 64-бита

mov ebx, edx ; копируем в ebx значение edx для дальнейшего оперирования обеими копиями значения

mov ecx, 10 ; для извлечения минимального десятичного числа будем делить на 10

nxt:

dec esi ; позиция следующего символа

xchg eax, ebx ; делим ...

xor edx, edx ; ... старшую ...

div ecx ; половину

xchg eax, ebx ; сохраняем частное

div ecx ; и делим остаток + младшую половину

add dl, 48 ; преобразуем в код соответствующего ASCII-символа

mov numRes[esi], dl ; сохраняем символ в буфер

mov edx, ebx ; возвращаем частное в edx

or edx, eax ; если оба частных равны нулю...

jnz nxt ; пойдём к следующей по порядку инструкции, иначе вернёмся в начало цикла

test x, 1 ; тест на знак числа ответа

jz pls

jnz mns

pls:

invoke crt_printf, ADDR formatStr, ADDR msgInputRes ; текст-пояснение 'Result is'

JMP EProg

mns:

invoke crt_printf, ADDR formatStr, ADDR msgInputResm ; текст-пояснение 'Result is -'

JMP EProg

EProg:

mov edx, offset numRes ; запоминаем адрес начала массива

add edx, esi ; добавляем смещение до первого символа, теперь в edx адрес первого символа строки результата

invoke crt_printf, ADDR formatStr, edx ; выводим результат вычислений на экран (десятичное число) целая часть

; вывод на экран дробной части

cmp edi, 0

jl mesgg ; <

jg mesgg ; >

jz mesg ; =

mesg:

invoke crt_printf, ADDR formatStr, ADDR msgInputOst ; если дробной части нет

JMP EndPrg

mesgg:

mov eax, edi ; если она есть

xor edx, edx

xor esi, esi

xor dl, dl

mov esi, BSIZE ; устанавливаем счётчик цикла равным длине максимального десятичного числа, помещающегося в 64-бита

mov ebx, edx ; копируем в ebx значение edx для дальнейшего оперирования обеими копиями значения

mov ecx, 10 ; для извлечения минимального десятичного числа будем делить на 10

nxtt:

dec esi ; позиция следующего символа

xchg eax, ebx ; делим ...

xor edx, edx ; ... старшую ...

div ecx ; половину

xchg eax, ebx ; сохраняем частное

div ecx ; и делим остаток + младшую половину

add dl, 48 ; преобразуем в код соответствующего ASCII-символа

mov numRes[esi], dl ; сохраняем символ в буфер

mov edx, ebx ; возвращаем частное в edx

or edx, eax ; если оба частных равны нулю...

jnz nxtt ; пойдём к следующей по порядку инструкции, иначе вернёмся в начало цикла

invoke crt_printf, ADDR formatStr, ADDR msgInputOstt ; выводим знак ","

mov edx, offset numRes ; запоминаем адрес начала массива

add edx, esi ; добавляем смещение до первого символа, теперь в edx адрес первого символа строки результата

invoke crt_printf, ADDR formatStr, edx ; выводим само число

JMP EndPrg

EndPrg:

ret ; возврат управления вызвавшей программе

arifm endp ; конец процедуры arifm

end start ; выполнение программы начнётся с метки start

Соседние файлы в папке КР1_В5