Подключение библиотеки к программе - 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

Объяснение кода листинга программы

  1. .model small - это директива компилятора, которая определяет сегментный состав и размер стекового фрейма, а также сегмент данных и кода. В данном случае, модель малого размера (small), сегмент данных (data) и сегмент кода (code) имеют размер 16 бит.
  2. if1 include laba1.lib - это команда препроцессора, которая подключает библиотеку с именем lab1.lib. Библиотека lab1.lib содержит процедуры и функции, которые могут быть использованы в этой программе.
  3. .stack 100h - это директива компилятора, которая определяет размер стека в 100 байтов.
  4. .data - это сегмент данных программы. Здесь определяются переменные, которые будут использоваться в программе.
  5. x dw ? - это определение переменной x в сегменте данных. Значение переменной не определено (знак вопроса), потому что оно будет определено позже в коде программы.
  6. y dw ? - это определение переменной y в сегменте данных. Значение переменной не определено (знак вопроса), потому что оно будет определено позже в коде программы.
  7. Result dw ? - это определение переменной Result в сегменте данных. Значение переменной не определено (знак вопроса), потому что оно будет определено позже в коде программы.
  8. CrLf db 0Dh, 0Ah, '$' - это определение строки CrLf, которая содержит символы новой строки (0Dh) и символы возврата каретки (0Ah). Строка заканчивается символом $.
  9. mes db 'Result X+Y= ', '$' - это определение строки mes, которая содержит текст Result X+Y=. В конце строки есть символ $, который используется для обозначения конца строки.
  10. KeyBuf db 7, ?, 7 dup(?) - это определение буфера ввода KeyBuf. Буфер содержит строку, которая включает символ 7, затем неопределенное количество символов, а затем 7 повторяющихся символов ?.
  11. main proc - это определение процедуры main. Эта процедура является точкой входа в программу.
  12. read x, KeyBuf, CrLf - это команда чтения ввода с клавиатуры. В данном случае, считываются значения переменных x и y из буфера ввода KeyBuf.
  13. umn x, y, Result - это команда вычисления суммы переменных x и y и сохранения результата в переменной Result.
  14. write mes, Result, CrLf - это команда вывода строки mes на экран, за которой следует значение переменной Result, а затем строка CrLf.
  15. mov ax, Result - это команда перемещения значения переменной Result в регистр AX.
  16. Show_AX proc - это определение процедуры Show_AX. Эта процедура используется для отображения значений 16-разрядных чисел на экране.
  17. or ax, ax - это команда проверки на отрицательность числа в регистре AX. Если число отрицательное, то на экране будет выведен символ -.
  18. neg ax - это команда инвертирования знака числа в регистре AX.
  19. @@Conv: - это метка точки перехода в процедуре Show_AX. Эта метка используется для обработки цифр числа в регистре AX.
  20. pop di - это команда выхода из цикла, который используется для вывода цифр числа на экран.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.429 из 5