Обсуждаем контроллеры компании Atmel.
Ответить

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сб дек 23, 2023 20:37:52

:facepalm:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вс янв 14, 2024 13:31:45

Ребята подскажите,...
Если я использую директиву dseg, то должен и начало в ней указывать (org) и также должен смещать начало сегмента cseg, относительно этого... ? И да, один адрес - это один байт?

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вс янв 14, 2024 14:28:10

Ребята подскажите,...
Если я использую директиву dseg, то должен и начало в ней указывать (org) и также должен смещать начало сегмента cseg, относительно этого... ? И да, один адрес - это один байт?

Насколько понимаю, это так, кроме слов о смещении сегмента cseg. Это разные области памяти и размеры разные и не связанные. Для dseg - org по байтам. В cseg - org словами из двух байт.
Да и заморачиваться по этому поводу незачем. Есть метки. В своих проектах на asm использую двух файловое построение (ядро и основная программа)
Ядро:
Код:
.Dseg
.org 0x100
;До 100H использовать нельзя - там РОН и порты ввода-вывода, отраженные на ОЗУ
;Переменные разной  размерности
;          byte   N   
EndCoreDseg:                  ;Адрес конца сегмента данных   в файле UNIT
.CSEG
.org 0x00                        
;   interrupt
;       и прочее
;Основной LOOP
;и прочие подпрограммы
EndCoreCSeg:                  ;Адрес конца кодового сегмента в файле UNIT


Основная программа
Код:
;Определение контроллера
.include "m328pdef.inc"                   
;секция всяких define и org
;#define
.include "unit.inc"
;Сегмент данных MAIN. Продолжаем с адреса конца сегмента UNIT
.Dseg            
;Переменные разной  размерности
;          byte   N   
.org EndCoreDseg
;Сегмент кода MAIN. Продолжаем с адреса конца сегмента UNIT
.CSEG
.org EndCoreCSeg
;код

Файлов в проекте может быть и много. В любом случае каждый сегмент должен где-то начаться. Cseg c своего 0 (вектора и начало в случае полного проекта), а Dseg со своей 100H или дальше.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вс янв 14, 2024 15:55:14

CSEG пространство памяти программ. Flash память.
DSEG Пространство SRAM. ОЗУ.

Начальный адрес для DSEG можно не указывать. Компилятору по заголовочному файлу на конкретный МК известен начальный адрес SRAM.

Адрес это начало. А один байт или два и так далее для этого тоже есть директивы.

Скачайте книгу Вольфганг Трамперт. AVR-RISC микроконтроллеры. Архитектура, аппаратные ресурсы, система команд, программирование, применение.

Там подробно расписано. И примеры на ассемблере. Эта книга долгое время была у меня настольной.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вс янв 14, 2024 18:21:01

Спасибо.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вт янв 16, 2024 10:34:14

Использование флагов, переменных, констант из области SRAM можно описать директивой .EQU.
Где .EQU имя_параметра = адрес_в_SRAM. В таком случае обращение (чтение/запись/модификация) к ячейке памяти можно выполнять по имени параметра.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вт янв 16, 2024 12:47:06

Определять переменные и константы находящиеся с области памяти (не важно RAM, EEPROM или FLASH) через .equ можно, но не очень удобно и есть опасность нарушить границы переменных, о чем вам компилятор не сообщит. Лучше делать метками это в соответствующих сегментах DSEG, ESEG и CSEG соответствующими директивами (.db, .dw, .byte и т.д.). Так и нагляднее и размер переменной легко задать и адрес следующей сам вычисляется, и определение адреса другой переменной из другого модуля программы в этот адрес не залезет.

.org обычно нужно ставить только если кусок памяти до этого адреса нужно пропустить, например в таблице векторов прерываний, чтобы не забивать пустые векторы NOP-ами или RJMP-ами на обработчик ошибки - просто делаете .org "имя прерывания" (которое из файла XXdef.inc берется) а потом RJMP на обработчик и все понятно и наглядно. Или если нужно чтоб какая-то переменная ну точно всегда была по определенному адресу, вот тогда если будет конфликт адресов, компилятор на это ругнется.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вт янв 16, 2024 17:05:35

.EQU удобна для описания битовых данных (флаги, линии портов, биты РСФ) ежли оные уже ранее не были определены.
Или для применяемых в программе констант.
Может также использоваться для присвоения данным с ранее определенным именем нового имени (получение разных имен для одни и тех же данных).
Не может быть переопределена далее по тексту программы (без применения .UNDEF), в отличии от .SET, которая позволяет менять значение метки ниже по тексту новой директивой .SET.
8)

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Вт янв 16, 2024 21:53:01

Честно скажу, я не совсем Вас понимаю, в чем состоит неудобство использования именованной, с помощью данной директивы, переменной в Ассемблере. Возможно это дело привычки. Но на мой взгляд все совсем наоборот. Хотя на вкус и цвет...

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Ср янв 17, 2024 09:43:18

Для программы на ассемблере существуют два вида данных:
1. данные (часто называемые "переменными"), которые размещаются в ячейках памяти;
2. данные константного типа, которые не имет фиксированного места размещения (константы, номера позиций бит в регистрах и/или байтах данных, размещенных в ОЗУ/ПЗУ).
Имена-метки для первого типа предпочтительно определять директивами разметки ОЗУ, ПЗУ, РСФ, регистрового банка.
Имена-метки второго типа исключительно удел .EQU или .SET
Дополнительные возможности .EQU - задать дополнительное имя метки данных к уже имеющемуся.
Однако для АВР относительно псевдонимов регистрового файла имеется еще директива .DEF
И их же (регистры регистрового файла) можно переразмечать как область ОЗУ.
Тут уже "свобода творчества" для автора программы.
8)

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Ср янв 17, 2024 20:17:55

Честно скажу, я не совсем Вас понимаю, в чем состоит неудобство использования именованной, с помощью данной директивы, переменной в Ассемблере. Возможно это дело привычки. Но на мой взгляд все совсем наоборот. Хотя на вкус и цвет...

Неудобство состоит в том, что с помощью .equ вы не выделяете память, а просто подставляете число.
Еще одно неудобство в том, что если переменная более 1 байта, то вам придется выдумывать имена для каждого байта, а директивой var: .byte 4 вы выделяете переменной var четыре байта. И при этом Ассемблер с линкером имеет возможность контролировать размещение переменных в памяти. В отличии от...
Ну и обращаясь к нынешней среде разработки Атмела - МПЛАБ Х, при использовании .equ вы не сможете контролировать значения переменной в соответствующих окнах среды. Ибо вы фактически переменную не создали. И даже в Атмел студии мап-файл и шкала заполнения памяти данных останутся пустыми.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 04:33:05

Неудобство состоит в том, что с помощью .equ вы не выделяете память, а просто подставляете число. Еще одно неудобство в том, что если переменная более 1 байта, то вам придется выдумывать имена для каждого байта...
Не нужно забивать память пустой информацией. Ассемблер прекрасно обрабатывает определение ниже без использования памяти
Код:
.equ   Fo=3276909*3   ;300'000'033...300'000'003!!!!!!
.
.
.
   LDI   YH,HIGH((200-25)*Fo/1000/300-1)      LDI   YL,LOW((200-25)*Fo/1000/300-1); включить за 25мс до окончания 200мс периода

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 08:00:15

Ассемблер прекрасно обрабатывает определение ниже без использования памяти
Какое это имеет отношение к тому, что я сказал? Я в каком то месте говорил про неиспользование памяти? :facepalm:
Либо вы ничего не поняли, либо не желаете уйти от своих стереотипов.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 08:32:13

КРАМ писал(а):Я в каком то месте говорил про неиспользование памяти?
вот в этом месте:
КРАМ писал(а):Неудобство состоит в том, что с помощью .equ вы не выделяете память, а просто подставляете число.
и у меня встречный вопрос - зачем, по-твоему, константам выделять память? константа она и потому константа, что ей не нужно выделение памяти.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 16:19:42

зачем, по-твоему, константам выделять память?

Присвоение значения адреса метке через .equ является эрзац-методом выделения памяти.
Старичок, внимательно прочтите обсуждение... :facepalm:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 16:47:37

лично меня этот эрзац устраивает полностью.
мне проще написать
.equ name1 0x100
.equ name2 0x104
этим я выделил для name1 4 байта. и никаких других директив мне не надо.
а если мой подход кому-то не нравится, то скажу, что каждый делает, как ему нравится и как ему удобно.
в ассемблере распределением памяти занимается программист, а не компилятор. и я её (память) распределяю, как мне удобно.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 17:05:44

в ассемблере распределением памяти занимается программист, а не компилятор

А никто и не говорил, что директива .byte занимается распределением памяти. Эта директива говорит СРЕДЕ РАЗРАБОТКИ, что речь идет о памяти, а не о константе. Если проект состоит в мигании светодиодом, то вообще по барабану насколько кривой текст и о чем думал погромист во время его написания. Более-менее серьезный проект требует контроля за памятью и для этого есть инструменты в среде разработки.
Если лично вам на это болт положить, то из этого не следует, что и другим это надо делать.
ЗЫ. Две недели назад завершил разбор чужого проекта. Вот его как раз писал любитель equ. Типа вас.
Понять где массив, а где переменная и какая у кого разрядность без поллитра невозможно. Но чувак реально думал о себе много... :music:

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 17:12:59

Starichok51
Не совсем так...
У Вас просто созданы константы
name1 = 0х100 и name2 = 0x104
далее компилятор будет их подставлять в команды в качестве данных.
Вот, к примеру, один из вариантов моего проекта в плане "шапки распределения ресурсов"(или отдельным файлом ставится в проекте) - в нем все, кроме таблиц в ПЗУ памяти программ:
Спойлер
Код:
;
;         "def_ext_disp.txt"  файл объявленных имен, бит и констант
;
;----------
; variable definitions
;(таблица обьявленных имен)
;_____
;таблица обьявленных имен - пользовательские константы
;
 .equ ts_ssl = 40 ; (1,50) константа интервала смены значения атрибута (0,8S)
                  ; для теста в дебаггере =1
 .equ dp_pgk = 190 ; константа предгашения (OCR1A)
 .equ dp_rastr = 4000 ; константа интервала развертки кадра (ICR1)
 .equ dp_maxj = 3990 ; максимальный уровень яркости ШИМ (OCR1B)
 .equ dp_minj = 200 ; минимальный уровень яркости ШИМ (OCR1B)
 .equ dp_lenbuf = 4 ; для сегментного порта 4 для регистрового файла 8
 .equ t_mk_lenpak = 8 ; количество байт в пакете
    ; 4 сегментный код, 2 код яркости, 1 атрибут информации, 1=CRC
 .equ dp_mask = 0b11110111 ; начальная позиция активного анода в строке
 .equ dp_maoff = 0b01111000 ; маска отключения всех анодов
 .equ dp_seg_port = PORTB ; переименование порта вывода сегментов
 .equ dp_anod_port = PORTD ; переименование порта вывода анодов
; .equ dp_reg_port = PORTD ; переименование порта управляющих линий регфайла
 .equ t_mk_port = PORTD ; переименование порта линий межблочного обмена
 .equ dp_AN3 = 6 ; старшая (крайняя правая) позиция дисплея
 .equ dp_AN2 = 5
 .equ dp_AN1 = 4
 .equ dp_AN0 = 3 ; младшая (крайняя левая) позиция дисплея
 .equ t_mk_RxD = 0 ; линия входящих данных программного приемника (PORTD.0 ввод)
 .equ t_mk_Txd = 1 ; линия квитирования программного приемника (PORTD.1 вывод)
; .equ dp_DS0 = n ; линия данных регфайла 0
; .equ dp_DS1 = n ; линия данных регфайла 1
; .equ dp_DS2 = n ; линия данных регфайла 2
; .equ dp_DS3 = n ; линия данных регфайла 3
; .equ dp_DS4 = n ; линия данных регфайла 4
; .equ dp_DS5 = n ; линия данных регфайла 5
; .equ dp_DS6 = n ; линия данных регфайла 6
; .equ dp_DS7 = n ; линия данных регфайла 7
; .equ dp_SH_CP = n ; общая линия строба сопровождения блока регфайлов
; .equ dp_MR = n ; общая линия строба сброса блока регфайлов
; .equ dp_ST_CP = n ; общая линия строба записи в защелку блока регфайлов
  .equ s_A = 0 ; номер сегмента A в знакогенераторе
  .equ s_B = 1 ; номер сегмента B в знакогенераторе
  .equ s_C = 2 ; номер сегмента C в знакогенераторе
  .equ s_D = 3 ; номер сегмента D в знакогенераторе
  .equ s_E = 4 ; номер сегмента E в знакогенераторе
  .equ s_F = 5 ; номер сегмента F в знакогенераторе
  .equ s_G = 6 ; номер сегмента G в знакогенераторе
  .equ s_H = 7 ; номер сегмента H в знакогенераторе
;
;_____
;таблица обьявленных имен - секция флагов пользователя
;
 .equ dp_exch = 0 ; флаг готовности новых данных в rdbf и rabf
 .equ dp_s_end = 1 ; передаточный флаг "строка окончена"
 .equ dp_darks = 2 ; флаг "интервал на темной стороне"
 .equ netpak = 3 ; флаг "прием пакета" для обхода заголовочной части
               ; участка обработчика байт приемника Т_МК
 .equ netdbu = 4 ; оперативный буфер приема занят
 .equ er_crc = 5 ; флаг "ошибка CRC"
;_____
;таблица обьявленных имен - переназначение регистров РОН
;
;             принята базовая модель:
; область ограниченного функционала
 .def mfr0 = r0  ; математика и обмен с ПЗУ/самопрограммирование
 .def mfr1 = r1  ; математика и обмен с ПЗУ/самопрограммирование
 .def dp_flags = r2 ; системные флаги (ограниченный функционал)
 .def how_sreg_d = r3  ; быстрый стек для SREG для irq дисплея
 .def how_sreg_n = r4  ; быстрый стек для SREG для irq USART
; .def ifr1=r5  ; системные индексы (ограниченный функционал)
; .def cfr0=r6  ; системные счетчики (ограниченный функционал)
; .def cfr0=r7  ; системные счетчики (ограниченный функционал)
 .def dp_xbuf = r8  ; оперативный буфер сегментов (байтовый режим)
 .def dp_masbu = r9 ; маска текущего активного анода
 .def dp_idx = r10  ; смещение в строке (номер кадра)
 .def dp_cntk = r11  ; счетчик кадров в строке
 .def dp_ftmpl = r12 ; быстрый стек (для r16/tmp0)
 .def dp_ftmph = r13 ; быстрый стек (для r17/tmp1)
 .def dp_ftmxl = r14 ; быстрый стек для Xl
 .def dp_ftmxh = r15 ; быстрый стек для Xh
; область полного функционала
 .def tmp0 = r16 ; рабочий регистр (полный функционал)
 .def tmp1 = r17 ; рабочий регистр (полный функционал)
 .def ts_cntss = r18 ; счетчик строк на шаг смены атрибута (полный функционал)
 .def tmp3 = r19 ; рабочий регистр (полный функционал)
 .def cntb = r20 ; рабочий регистр (полный функционал)
 .def cntw=r21 ; рабочий регистр (полный функционал)
; .def wfr6=r22 ; рабочий регистр (полный функционал)
; .def wfr7=r23 ; рабочий регистр (полный функционал)
 .def bfr0 = r24 ; базовый регистр (полный функционал)
 .def bfr1 = r25 ; базовый регистр (полный функционал)
;     Xl = r26 ; адрес сегмента Х (полный функционал)
;     Xh = r27 ; адрес сегмента Х (полный функционал)
;     Yl = r28 ; адрес сегмента Y (полный функционал)
;     Yh = r29 ; адрес сегмента Y (полный функционал)
;     Zl = r30 ; адрес сегмента Z (полный функционал) ПЗУ/самопрограммирование
;     Zh = r31 ; адрес сегмента Z (полный функционал) ПЗУ/самопрограммирование
; регистры Xh:Xl, Yh:Yl, Zh:Zl определены в дефайне изготовителя и в системе команд
; изменение их имени хотя и возможно, но нежелательно -
; возникает путаница с интегрированной абревиатурой системы команд
;  в случае с "малой моделью" допускающей/достаточной для размещения ВСЕХ
; используемых ВСЕМИ подпрограммами регистров в области СОЗУ регистрового
; файла одновременно (без "подкачки" наборов параметров через ОЗУ)
; рекомендовано переназначение индивидуальных имен регистров
; согласно текущей задачи
;_____
;таблица обьявленных имен - секция определенных данных (ОЗУ)
;
   .dseg
 dp_datbuf: .byte dp_lenbuf ; буфер отображения: данные (4 позиции)
; младшая позиция в ячейке dp_datbuf, старшая в dp_datbuf+3
 dp_atrbuf: .byte (dp_lenbuf*2) ; буфер отображения: задатчик ШИМ по каждой позиции
 dp_rdbf:   .byte dp_lenbuf ; буфер предобработки данных
 dp_rabf:   .byte (dp_lenbuf*2) ; буфер предобработки задатчика ШИМ
 dp_shaps:  .byte 3 ; значения для dp_cntk, dp_masbu и dp_idx по запуску строки
 dp_cnts:   .byte 1 ; счетчик строк на сдвиг (беглая строка)
 dp_cntb:   .byte 1 ; счетчик бит в байте модуля вывода
;          в файл-расширитель горизонтальной координаты
 dp_cntwf:  .byte 1 ; счетчик байт модуля вывода
;          в файл-расширитель горизонтальной координаты
 net_fsr:   .byte 2 ; указатель адреса в буфере предобработки
;          для pakus
 net_cnt:  .byte 1 ; счетчик байт пакета для pakus
 net_buf:  .byte 8 ; оперативный буфер приема
;
;_____
;таблица обьявленных имен - секция определенных данных (EEPROM)
;
  .eseg
;_____

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 17:26:43

BOB51, да, я объявил константы.
но когда я их подставляю в команду, они оказываются адресами в ОЗУ.
КРАМ писал(а):Более-менее серьезный проект требует контроля за памятью
я не кладу болт на распределение памяти - тот пример, который я написал, и есть мой контроль за памятью. обращаясь к памяти по созданным именам я никогда не выйду за пределы имеющейся памяти.
и я не говорил, что другим это надо делать так же. я говорил, что каждый делает, как ему удобно.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Чт янв 18, 2024 17:36:58

как ему удобно.

Нет, каждый делает ГЛУПОСТИ как ему удобно. До тех пор, пока грабли не ударят больно по лбу.
Нет ничего "удобного" в equ против byte. Ну кроме того, что вместо наблюдения за переменными в окне Watch по имени, человек ищет в Memory по адресу, метаясь по листингу от списка переменных к конкретному участку кода.
А так - да, охрененно удобно... :))) :))) :)))
Ответить