Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.10.2021, 17:17   #11
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

Вот так сработало:
Код:
$include (REG51.H)
;.CHIP   8051

QUARZ   EQU     4046            ;ЧАСТОТА КВАРЦА В kHz
KEY     EQU     P0.1
ZV      EQU     P0.5
ForenLi, спасибо! Но есть еще ошибки синтаксиса
devel2011 вне форума Ответить с цитированием
Старый 26.10.2021, 17:44   #12
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

Дальше словил Error A22: Expression type does not match instruction
Код:
        ORG     23H

        PUSH    A
        PUSH    PSW
        SETB    RS1
        CLR     RS0
        POP     PSW
        POP     A
        RETI
Судя по базе знаний Keil, здесь аккумулятор необходимо записывать как ACC. Проверил - работает.

Дальше стопорится на такой конструкции:
Код:
        MOV     A,FLGA          ;|
        JB      A.0,ZV1         ;||
Синтаксическую ошибку вызывает A.0, насколько я понимаю. Т.е. сначала в А заносится байт из FLGA, а затем JB обращается к 1-му биту, проверяя его на 1. Правильно я думаю, что здесь аналогично, нужно использовать ACC? И какая запись будет синтаксически верной, такая:
Код:
        MOV     AСС,FLGA          ;|
        JB      AСС.0,ZV1         ;||
,
или такая:
Код:
        MOV     A,FLGA          ;|
        JB      AСС.0,ZV1         ;||
Компилятор пропускает обе. Или можно любой использовать вариант? Аккумулятор то, по-сути, один.

Последний раз редактировалось devel2011; 26.10.2021 в 17:51.
devel2011 вне форума Ответить с цитированием
Старый 26.10.2021, 18:11   #13
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

Вот еще непонятная конструкция:
Код:
FLGREJ: MOV     A,R0            ;УБРАТЬ ФЛАГ РЕЖИМА
        JB      ACC.2,FLGRB       ;
FLGRA:  ANL     (7),#.NOT.REJIMA ;ФЛАГ-РЕЖИМ А ОБРАБОТАН
        RET                     ;
FLGRB:  ANL     (7),#.NOT.REJIMB ;ФЛАГ-РЕЖИМ В ОБРАБОТАН
        RET                     ;
Описание ANL явно определяет, что первый операнд - это байт приемник. Какой приемник может быть записан как (7)? Что-то дикое тут написано, не поддающееся моему разуму =)
devel2011 вне форума Ответить с цитированием
Старый 26.10.2021, 23:05   #14
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

Вот что я нашел по правой части выражения, которое постом выше:
Цитата:
Ассемблер A51 допускает использование выражений в поле операндов, значения которых вычисляются в процессе трансляции.

Выражение представляет собой совокупность символических имен и чисел, связанных операторами ассемблера. Операторы ассемблера обеспечивают выполнение арифметических (“+” - сложение, “-” - вычитание, “*” - умножение, “/” - целое деление, MOD – деление по модулю) и логических (OR - ИЛИ, AND - И, XOR - исключающее ИЛИ, NOT - отрицание) операций в формате 2-байтных слов. Например, запись ADD A, #((NOT 13)+1) эквивалентна записи ADD A, #0F3H и обеспечивает сложение содержимого аккумулятора с числом -13, представленным в дополнительном коде.

Широко используются также операторы LOW и HIGH, позволяющие вычислить младший и старший байты 2-байтного операнда.
Полагаю, что Keil-у не нравятся еще и точки вокруг NOT. Или я не прав?
devel2011 вне форума Ответить с цитированием
Старый 27.10.2021, 02:48   #15
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

Из почти 600 ошибок осталось лишь 30. Запнулся на арифметике. Заданы константы:
Код:
QUARZ   EQU     4046            ;ЧАСТОТА КВАРЦА В kHz
TIK0    EQU		600             ;600 mkS
OST00   EQU     (TIK0*QUARZ MOD 12000)/6000
CORTM0  EQU     (TIK0*QUARZ/12000+OST00)
ZNAM    EQU     12*(CORTM0)
OST01   EQU     (30*QUARZ MOD ZNAM)/(ZNAM/2)
Получаю в OST01 ошибку деления на ноль. Выходит, что не считается ZNAM (а следовательно, и CORTM0). Или я ошибся в синтаксисе MOD, или в приоритетах арифметических команд.
Закинул эти выражения в Python, - все считается нормально, нуля нет. Циферки норм.
Нужна помощь зала ...
devel2011 вне форума Ответить с цитированием
Старый 27.10.2021, 11:28   #16
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,647
По умолчанию

Может быть, компилятор при вычислении констант применяет целочисленное деление. Тогда если CORTM0 < 1, получится 0.
Облегчить ему работу: вычислить вручную эти константы и подставить в исходник. 5 минут...
digitalis вне форума Ответить с цитированием
Старый 27.10.2021, 12:39   #17
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

digitalis, благодарю.
В целом, да - константы пляшут от кварца, внося корректировки. А кварц уже есть, и его частота известна. Значит действительно, проще вычислить константы один раз, и объявить их.
Но дальше в коде есть еще похожие конструкции, как бы они не оказались тоже нерабочими. Синтаксис похожий. Для кварца 4046кГц константы вычисляются такие:
Код:
OST00 0.6
CORTM0 202.9
ZNAM 2434.8
OST01 1.7042878265155175
Для кварца 4000кГц:
Код:
OST00 0.0
CORTM0 200.0
ZNAM 2400.0
OST01 0.0
Видим, что CORTM0 не бывает ниже 1. Как бы проверить, что считает компилятор?
devel2011 вне форума Ответить с цитированием
Старый 27.10.2021, 14:49   #18
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,647
По умолчанию

Так он же листинг выдаёт (должен выдавать) - там всё видно.
Я с 51-м не работал, но к примру, для AVR - AvrAsm выдаёт в листинге всё нужное. Если есть в программе непосредственный операнд, то его значение в HEX-системе будет в листинге.
digitalis вне форума Ответить с цитированием
Старый 27.10.2021, 15:09   #19
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

Ага! Открыл листинг, и там константы с формулами после EQU по нулям. Константы-числа Ок. Поэтому и кривеет все ниже. Значит, формулу надо курить.
Еще нашел любопытную конструкцию:
Код:
        MOV     A,#DELAY       
        DJNZ    A,$
Выяснил, что это просто временная задержка. Компилятору не нравится знак '$'. Пока придумал поставить метку перед MOV, и заворачивать цикл на нее вместо $. Может есть более красивый (правильный) способ?
devel2011 вне форума Ответить с цитированием
Старый 27.10.2021, 16:05   #20
devel2011
Пользователь
 
Регистрация: 24.10.2021
Сообщений: 17
По умолчанию

C арифметикой получается следующее: умножение TIK0*QUARZ, например, получается слишком большим (предел почему-то 65535), а деление действительно целочисленное. Результат в листинге записан в 16-м формате, 4 разряда. Если есть переполнение в расчете - в листинге нули. MOD работает. Я так понимаю, по аналогии с другими языками, надо как-то определить тип константы (float), хотя как компилировалось в родной среде без этого - не понятно...

И еще вопрос: в каком порядке выполняется это действие:
Код:
QUARZ/1000*100/12/2
Скобок нет, и я предполагаю, что слева направо, сначала делится QUARZ на 1000, затем результат умножается на 100, делится на 12, и еще на 2. Правильно я рассуждаю?

Последний раз редактировалось devel2011; 27.10.2021 в 16:18.
devel2011 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка. Берём hex-код, шифруем hex-код, собираем всё в файл. Poltish Общие вопросы Delphi 2 21.08.2013 12:57
file->HEX HEX->BIN kakawkin Общие вопросы Delphi 1 25.04.2012 01:02
По HEX kompaky Общие вопросы по программированию, компьютерный форум 2 30.07.2011 19:12
Помогите с hex в с++ pavelstraut Помощь студентам 1 17.07.2009 23:29
C# и HEX megazz13 Помощь студентам 2 03.04.2009 00:32