Виснет программа при запуске

Рейтинг: 0Ответов: 2Опубликовано: 27.05.2023

Только начал заниматься ассемблером, поэтому трудно разобраться в чем проблема. Программа должна выводить график функции на экран. Компиляцию сделал, слинковал, пробовал запустить через TD, но все равно начинает виснуть. Может кто тут поможет решить в чем проблема?

.model small
.stack 100h

.data
    x dw 0
    y dw 0
    a dw 3
    b dw 2
    c dw 1

.code
Start:mov ax, @data
    mov ds, ax
    mov ah, 0
    mov al, 13h ; графический режим
    int 10h

    ; настройка цветов
    mov ax, 1003h
    mov bx, 0000h ; белый цвет для осей
    int 10h

    mov cx, 501 ; количество точек графика
    mov dx, 0 ; начальное значение x
    mov ax, 0 ; начальное значение y
    mov bx, 0 ; значение цвета
    mov si, 320 ; координата X для центрирования графика

    draw_graph:
        ; рассчитываем значение y
        mov ax, dx
        mul dx
        mul dx
        mov bx, ax
        mov ax, dx
        mul a
        add bx, ax
        mov ax, b
        mul dx
        add bx, ax
        add bx, c

        cmp bx, 0 ; проверяем условие для цвета
        jl below_zero
        mov bx, 12h ; красный цвет
        jmp draw
        below_zero:
            mov bx, 09h ; синий цвет
        draw:
            mov ah, 0Ch ; рисуем точку графика
            mov al, bl ; цвет
            mov cx, dx
            add cx, si ; центрируем график по X
            mov dx, bx
            int 10h

        ; выводим координаты точки пересечения
        cmp dx, y
        jne next
        mov ah, 0Ch ; рисуем точку на пересечении осей
        mov al, 0Fh ; ярко-белый цвет
        mov cx, dx
        add cx, si
        mov dx, 200
        int 10h
        mov ah, 09h ; выводим координаты точки пересечения
        mov dx, offset message
        int 21h
        mov ah, 02h ; выводим координату X
        mov dl, 'X'
        int 21h
        mov ax, dx
        add ax, si
        mov dx, ax
        call print_number
        mov ah, 02h ; выводим координату Y
        mov dl, 'Y'
        int 21h
        mov ax, y
        call print_number
        jmp done
        next:
            cmp dx, y
            jg above
            mov y, dx
            jmp done
            above:
                jmp done

        ; увеличиваем x и продолжаем рисовать график
        inc dx
        loop draw_graph

    done:
        ; сохраняем график в текстовый файл
        mov ah, 3Dh ; создаем файл
        mov al, 0 ; режим чтения/записи
        mov dx, offset filename ; имя файла
        int 21h
        mov bx, ax ; номер файла
        mov ah, 40h ; записываем в файл
        mov cx, 2 ; количество байтов для записи
        mov dx, offset x ; координата X точки пересечения
        int 21h
        mov cx, 2 ; количество байтов для записи
        mov dx, offset y ; координата Y точки пересечения
        int 21h
        mov ah, 3Eh ; закрываем файл
        int 21h

        mov ah, 4Ch ; возвращаем управление операционной системе
        int 21h

    ; функция для вывода числа
    print_number proc
        push ax
        push bx
        push cx
        push dx

        mov bx, 10
        xor cx, cx
        div bx
        or dx, 30h
        mov ah, 02h
        int 21h
        mov ax, cx
        cmp ax, 0
        je skip
        call print_number
        skip:
            pop dx
            pop cx
            pop bx
            pop ax
            ret
    print_number endp

.data
    filename db 'graph.txt',0
    message db 'Intersection point: X=',0

end Start

Ответы

▲ 0

Проблема в том, что программа бесконечно рисует график, и не выходит из цикла. Надо добавить условие выхода из нее.

        ; увеличиваем x и продолжаем рисовать график
        inc dx
        loop draw_graph

        ; условие выхода из цикла
        cmp dx, 500
        jne draw_graph

    done:
        ; сохраняем график в текстовый файл и т.д.
▲ -1

См. пример (выполнение начинается сразу после org 100h ; данные располагаются в конце)

.model  tiny
                .code
                org     100h
                                           ; начало выполнения
start:          mov     dx, offset str
                mov     ah, 09h            ; команда вывода строки
                int     21h                ; вызов прерывания
                ret
str             db      'Hello, World!',0
                end     start