Почему AL получает значение ноль каждый раз? - PullRequest
0 голосов
/ 11 июня 2019

al всегда получает нулевое значение вместо подсчета времени выполнения программы.Я должен печатать @ каждые 5 секунд, используя порты 70 и 71 блока часов.

.model small

.data

.code

msg db '@ $'
lastv db 0
saver db 0

start:      


    mov ax, @data
    mov ds, ax

    PollClock: 


        mov al, 00h  ; set operation to count seconds
        out 070h, al   ; set operation to count seconds
        in  al, 071h    ; any write to 0x70 should be followed by an action to 0x71 or the RTC will be left in an unknown state
        mov saver, al

        mov ah, 0h
        mov bl, 5h
        div bl

        test ah, ah ;check if reminder is zero
        jnz PollClock

        mov al, saver
        cmp lastv, al
        jne PollClock

        mov  dx, offset msg
        mov al, 0h
        mov  ah, 09h        
        int  21h
        inc lastv


    jmp PollClock


    mov ah, 04ch
    int 21h
end start

1 Ответ

3 голосов
/ 11 июня 2019

Проверка на lastv для предотвращения зацикливания в одну и ту же секунду несколько раз неверна.

Он должен использовать je PollClock (обратите внимание на отсутствие n), чтобы вернуться к циклу, если текущая секунда все еще равна последней сохраненной.
Более того, вы не обрабатываете lastvправильно:

  • Вы инициализируете его с 0, который является действительным кратным 5. Это заставит вашу программу пропустить первый удар, если он окажется на втором 0 (то есть на минутной границе).
  • Вы не сохраните его после теста делимости.Если вы не увеличивали его после печати (соблюдайте вышеприведенное условие jne), ваша программа будет печатать каждую минуту, но с этим шагом она будет печататься только один раз (когда наступит минута), поскольку будущие итерации потребуютсекунда, которая будет кратна 5 и равна 1.

Вы должны:

  • Инициализировать lastv переменную с невозможным значением (например, не кратным5 или просто 0ffh, который находится вне диапазона в течение секунд)
  • Преобразование jne в je
  • Сохраните значение al в lastv перед печатью
  • Удалите inc lastv

lastv db 0ffh           ;Changed and moved

...

mov al, saver
cmp lastv, al
je PollClock            ;Changed

mov lastv, al           ;Added

...

;inc lastv              ;Commented

Но перед этим необходимо переместить переменные в сегмент данных, в противном случае доступ к ним осуществляется через ds (неявный сегментный регистр) не даст вам правильных значений.
Это особенно важно для строки msg.


Extra

CMOS немного сложнее, чем , формат даты может быть двоичным или BCD.
Для этого приложения это не имеет значения, хотя.

Также имеется бит обновления даты, который необходимо проверить перед считыванием полное дата-время.
Опять же, в этом простом приложении (где считываются только секунды) это не имеет значения.

Наконец, если у вас есть желание экспериментировать с программированием на основе прерываний, вы можете перехватить int 1ch, который вызывается обработчиком IRQ0 (int 08h) или используйте периодическое прерывание CMOS на линии IRQ8 (int 70h) после программирования условий запуска.

Существует также служба ожидания (int 15h/ah=86h), хотя обычно это бесполезно, поскольку DOS не является многозадачной.

...