Подключение библиотеки к программе - Assembler
Формулировка задачи:
В общем, требуется подключить библиотеку к программе (primer.lib) и в этой библиотеке должны быть функции:
read - чтение числа с клавиатуры (считывается строка и преобразовывается в десятичное число)
write - вывод числа на экран
Сложение я реализовал
Проблема с read и write. Они не работают должным образом.
В случае с read, программа попросту зацикливается, когда я вызываю данный макрос. А с write - здесь на вход дюже много параметров подается (такая же история и с read кстати). Т.е. пример: read macro p, KeyBuf1, PromptX, CrLf1. В идеале бы сделать так, чтобы остался только параметр p - вводимая строка, которая преобразуется в число. Аналогичная ситуация и с write. Нужно сделать так, чтобы был макрос write a, где a - выводимое число.
Также программа запускается (хоть и зацикливается) только если я вставляю read единажды. Если мне нужно ввести X и Y, т.е. ставлю 2 read, то высыпается куча ошибок.
Вот что я написал. Основная программа:
А это библиотека:
Жуть какая-то, помогите, пожалуйста, доделать это.
Title prog (EXE) ; основная программа if1 include primer.lib endif StackSg Segment PARA STACK 'Stack' DW 64 DUP(?) StackSg ENDS DataSg Segment PARA 'Data' Prompt1 db 'Enter X: ', '$' Prompt2 db 'Enter Y: ', '$' sResult db 'Result = ', '$' CrLf db 0Dh, 0Ah, '$' X dw 15 Y dw ? Result dw ? KeyBuf db 7, ?, 7 dup(?) DataSg ENDS CodeSg Segment PARA Public 'Code' Begin Proc FAR Assume CS:CodeSg, DS:DataSg, SS:StackSg Push DS Sub AX, AX Push AX Mov AX, DataSg Mov DS, AX read x, KeyBuf, Prompt1, CrLf read y, KeyBuf, Prompt2, CrLf umn x, y, Result write sResult, Result, CrLf Ret Begin ENDP CodeSg ENDS END Begin
umn macro x1, y1, res2 mov ax, x1 mov bx, y1 mul bx mov res2, ax endm read macro p, KeyBuf1, PromptX, CrLf1 InputX: lea dx, PromptX mov ah, 09h int 21h mov ah, 0Ah mov dx, offset KeyBuf1 int 21h ; перевод строки (на новую строку) lea dx, CrLf1 mov ah,09h int 21h ; преобразование строки в число lea si, KeyBuf1+1 lea di, p call Str2Num ; проверка на ошибку jc InputX ; преобразования строки в знаковое число ; на входе: ; ds:[si] - строка с числом ; ds:[di] - адрес числа ; на выходе ; ds:[di] - число ; CY - флаг переноса (при ошибке - установлен, иначе - сброшен) Str2Num proc push ax push bx push cx push dx push ds push es push si push ds pop es mov cl, ds:[si] xor ch, ch inc si cmp [si], byte ptr '-' jne @@IsPositive inc si dec cx @@IsPositive: jcxz @@Error mov bx, 10 xor ax, ax @@Loop: mul bx ; умножаем ax на 10 ( dx:ax=ax*bx ) mov [di], ax ; игнорируем старшее слово cmp dx, 0 ; проверяем, результат на переполнение jnz @@Error mov al, [si] ; Преобразуем следующий символ в число cmp al, '0' jb @@Error cmp al, '9' ja @@Error sub al, '0' xor ah, ah add ax, [di] jc @@Error ; Если сумма больше 65535 inc si loop @@Loop pop si push si or ax, ax js @@Error cmp [si+1], byte ptr '-' jne @@Positive neg ax or ax, ax jns @@Error @@Positive: mov [di], ax clc pop si pop es pop ds pop dx pop cx pop bx pop ax ret @@Error: xor ax, ax mov [di], ax stc pop si pop es pop ds pop dx pop cx pop bx pop ax ret Str2Num endp endm write macro mess1, res1, CrLf ;вывод результата mov ah, 09h lea dx, mess1 int 21h mov ax, res1 call Show_AX mov ah, 09h lea dx, CrLf int 21h mov ax, 4C00h int 21h Show_AX proc push ax push bx push cx push dx push di mov cx, 10 xor di, di ; di - кол. цифр в числе ; если число в ax отрицательное, то ;1) напечатать '-' ;2) сделать ax положительным or ax, ax jns @@Conv push ax mov dx, '-' mov ah, 2 ; ah - функция вывода символа на экран int 21h pop ax neg ax @@Conv: xor dx, dx div cx ; dl = num mod 10 add dl, '0' ; перевод в символьный формат inc di push dx ; складываем в стек or ax, ax jnz @@Conv ; выводим из стека на экран @@Show: pop dx ; dl = очередной выводимый символ mov ah, 2 ; ah - функция вывода символа на экран int 21h dec di ; повторяем пока di<>0 jnz @@Show pop di pop dx pop cx pop bx pop ax ret Show_AX endp endm
Решение задачи: «Подключение библиотеки к программе»
textual
Листинг программы
.model small if1 include laba1.lib endif .stack 100h .data x dw ? y dw ? Result dw ? CrLf db 0Dh, 0Ah, '$' mes db 'Result X+Y= ', '$' KeyBuf db 7, ?, 7 dup(?) .code main proc mov ax, @data mov ds, ax read x, KeyBuf,CrLf read y, KeyBuf, CrLf umn x, y, Result ;write mes, Result, CrLf mov ax, Result ; выводит знаковое 16-разрядное число из регистра AX на экран ; входные данные: ; ax - число для отображения Show_AX proc push ax push bx push cx push dx push di mov cx, 10 xor di, di ; di - кол. цифр в числе ; если число в ax отрицательное, то ;1) напечатать '-' ;2) сделать ax положительным or ax, ax jns @@Conv push ax mov dx, '-' mov ah, 2 ; ah - функция вывода символа на экран int 21h pop ax neg ax @@Conv: xor dx, dx div cx ; dl = num mod 10 add dl, '0' ; перевод в символьный формат inc di push dx ; складываем в стек or ax, ax jnz @@Conv ; выводим из стека на экран @@Show: pop dx ; dl = очередной выводимый символ mov ah, 2 ; ah - функция вывода символа на экран int 21h dec di ; повторяем пока di<>0 jnz @@Show pop di pop dx pop cx pop bx pop ax ret Show_AX endp main endp buff1 db 6,7 Dup(?) end main
Объяснение кода листинга программы
- .model small - это директива компилятора, которая определяет сегментный состав и размер стекового фрейма, а также сегмент данных и кода. В данном случае, модель малого размера (small), сегмент данных (data) и сегмент кода (code) имеют размер 16 бит.
- if1 include laba1.lib - это команда препроцессора, которая подключает библиотеку с именем
lab1.lib
. Библиотекаlab1.lib
содержит процедуры и функции, которые могут быть использованы в этой программе. - .stack 100h - это директива компилятора, которая определяет размер стека в 100 байтов.
- .data - это сегмент данных программы. Здесь определяются переменные, которые будут использоваться в программе.
- x dw ? - это определение переменной
x
в сегменте данных. Значение переменной не определено (знак вопроса), потому что оно будет определено позже в коде программы. - y dw ? - это определение переменной
y
в сегменте данных. Значение переменной не определено (знак вопроса), потому что оно будет определено позже в коде программы. - Result dw ? - это определение переменной
Result
в сегменте данных. Значение переменной не определено (знак вопроса), потому что оно будет определено позже в коде программы. - CrLf db 0Dh, 0Ah, '$' - это определение строки
CrLf
, которая содержит символы новой строки (0Dh) и символы возврата каретки (0Ah). Строка заканчивается символом$
. - mes db 'Result X+Y= ', '$' - это определение строки
mes
, которая содержит текстResult X+Y=
. В конце строки есть символ$
, который используется для обозначения конца строки. - KeyBuf db 7, ?, 7 dup(?) - это определение буфера ввода
KeyBuf
. Буфер содержит строку, которая включает символ7
, затем неопределенное количество символов, а затем 7 повторяющихся символов?
. - main proc - это определение процедуры
main
. Эта процедура является точкой входа в программу. - read x, KeyBuf, CrLf - это команда чтения ввода с клавиатуры. В данном случае, считываются значения переменных
x
иy
из буфера вводаKeyBuf
. - umn x, y, Result - это команда вычисления суммы переменных
x
иy
и сохранения результата в переменнойResult
. - write mes, Result, CrLf - это команда вывода строки
mes
на экран, за которой следует значение переменнойResult
, а затем строкаCrLf
. - mov ax, Result - это команда перемещения значения переменной
Result
в регистр AX. - Show_AX proc - это определение процедуры
Show_AX
. Эта процедура используется для отображения значений 16-разрядных чисел на экране. - or ax, ax - это команда проверки на отрицательность числа в регистре AX. Если число отрицательное, то на экране будет выведен символ
-
. - neg ax - это команда инвертирования знака числа в регистре AX.
- @@Conv: - это метка точки перехода в процедуре
Show_AX
. Эта метка используется для обработки цифр числа в регистре AX. - pop di - это команда выхода из цикла, который используется для вывода цифр числа на экран.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д