Menu

Глюки при косвенном обращении к R0-RE

2017-09-07
2017-09-07
  • Фурс Александр

    В версии 0.35 при записи в какой-либо из регистров 0-E значения 4 и последующем косвенном обращении появляются следующие ошибки:

    для регистров 0-3 это значение декрементируется на две единицы (а не на одну) и становится равным двум;

    для регистров 4-6 значение не изменяется (хотя должно инкрементироваться) и остается равным четырем;

    для регистров 7-E значение декрементируется (хотя меняться не должно) и становится равным трем.

    После чего происходит косвенная запись, чтение или переход по сформированному ошибочному значению. Для более ранних версий наличие глюка не проверял, но в 0.26 он отсутствует.


    Обнаружил указанную ошибку по сбойной работе ранее написанной мною тестовой программы, вычисляющей 7960 знаков после запятой числа e:

    ; --- Число e ---
    
    ; расчетная формула - e - 1 = [ ... [[[1/N + 1]/(N-1) + 1]/(N-2) + 1]/(N-3) + ... + 1]/1    (*)
    
    ; ВВОД данных перед запуском не требуется
    
    ; ВЫВОД: знаки после запятой числа e в регистрах, начиная
        ; с 5-го - войти в режим просмотра десятичных данных;
    ; если число знаков в каком-либо регистре оказывается
        ; меньше константы DIG - значение дополнить слева нулями;
    
    ; в X - продолжительность работы в формате МММ.СС;
    ; в Y - первые DIG знаков (= значению регистра 5)
    
    MAX     .EQU 999    ; номер последнего регистра (5 <= MAX <= 999)
    DIG     .EQU 8      ; число знаков в одном регистре (от 1 до 8)
                    ; т.е. всех знаков SGN = (MAX - 4) * DIG
    
    N       .EQU 2662   ; число N: должно быть таким, чтобы lg(N!) > SGN
    DT      .EQU 500    ; промежуток обновления экрана - 5 секунд
    
    ; Используемые регистры
      ; 0 - текущий делитель в формуле (*), уменьшается от N до 1
      ; 1 - время запуска
      ; 2 - константа MAX
      ; 3 - константа 10^DIG
      ; 4 - индексный, номер регистра (от 5 до MAX)
      ; 5--MAX - для вывода знаков числа e
    
    .ORG 0
    
    BEG: PP RM9055 K MS->D M1       ; время запуска
    
              .NUM MAX M2 4 M4 - M0 CX  ; очистка регистров 5--MAX
    CLR: K M4
               F L0 CLR
    
               1 PP M9130 PP M9150      ; установка прерывания 1 на таймер 0
               .NUML INTR ENT 9 PP M9131
               2 PP M9050
    
               .NUM N M0 .NUM DIG F 10^X M3
    
    C1:  1 ENT 4 M4         ; вычисления
    C2:  <-> RM3 * K RM4 + ENT RM0 / K INT PK M4 RM0 * -
              RM2 RM4 -
              F X=0 C2
              F L0 C1
              RM5 RM3 - M5
    
              PP RM9055 K MS->D RM1 - 60 * K D->M   ; продолжительность работы
              R/S
              GOTO BEG
    
    INTR: CX ENT ENT RM0 K SCR      ; подпрограмма прерывания - периодический вывод
                .NUM DT PP M9050        ; текущего делителя в формуле (*)
                PP RTN
    
     

    Last edit: Фурс Александр 2017-09-07
    • Павел Петров

      Да, подводные камни двоичной арифметики всё ещё продолжают вылазить. В версии 0.34 я модифицировал арифметику, но один момент вот упустил. Доработанную windows-версию уже выложил, linux будет вечером.

       

Anonymous
Anonymous

Add attachments
Cancel