Ассемблер (ASM) для AVR в вопросах и ответах
Значит этот велосипед изобретен до нас, но я в принципе вообще никак не удивлен, раз работает - грех не воспользоваться.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
- Реклама
Меня одна тема приколола в описании СИшного компилятора IARовского. они там переменные не в ОЗУ запихивают, а в неиспользуемые регистры периферии. Таким образом экономят такты. Интересно придумали.
Ну молодцы, я тоже так делаю, особенно удобно для флагов (SBI/CBI гораздо удобнее чем LDS-ORI-STS/LDS-ANDI-STS). Мысля пришла сразу как только я увидел регистры GPIOR у тинек, которые прям специально для этого и нужны.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
Не используемую периферию (например UBRR в USART), доступную командам SBIC, SBIS, CBI, SBI использую для флагов условий. Очень удобно. 
Вот это вы понаписали
Изменение порядка разрешения прерываний на ногах INT и их настройка результатов не принесли
По поводу того, что там пишется в по адресу 0xc1, я уже сомневаюсь в правильности своего вопроса 
А сейчас вот что я хотел спросить. Как правильно работать с 2байтным числом?
Я резервирую себе некую переменную
А как в неё правильно записывать?
Как-то так:
Придумываем число 5638
Переводим его в 0001 0110 0000 0110
После этого
Читать также, только использовать 2 регистра под старшую и младшую часть.
Ничего не путаю?
А вот, например, чтобы увеличить или уменьшить число, как быть?
Проверять на 0 старшую часть и если она 0, то отнимать командой
от младшей части.
А если она больше 0, декреминировать старшую часть.
А если надо отнять какое-то фиксированное число?
Как-то делать через команду
Если у кого есть под рукой, можете кинуть примеры вычитаний и сложений, плз? Мне не лень покопаться, я этим, собственно, щас и занимаюсь, но просто времени много уйдёт.
Изменение порядка разрешения прерываний на ногах INT и их настройка результатов не принесли
А сейчас вот что я хотел спросить. Как правильно работать с 2байтным числом?
Я резервирую себе некую переменную
Код: Выделить всё
.dseg
c: .byte 2
Как-то так:
Придумываем число 5638
Переводим его в 0001 0110 0000 0110
После этого
Код: Выделить всё
ldi Temp0, 0b00000110 ;Загрузка в Temp0 младшего байта
STS c, Temp0 Загрузка в первый(младший) байт c Temp0
ldi Temp0, 0b00010110 ;Загрузка в Temp0 старшего байта
STS c+1, Temp0 Загрузка во второй(старший) байт c Temp0
Ничего не путаю?
А вот, например, чтобы увеличить или уменьшить число, как быть?
Проверять на 0 старшую часть и если она 0, то отнимать командой
Код: Выделить всё
dec
А если она больше 0, декреминировать старшую часть.
А если надо отнять какое-то фиксированное число?
Как-то делать через команду
Код: Выделить всё
SBC
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
- Реклама
Для операций со словами есть регистровые пары R25:R24, XH:XL, YH:YL, ZH:ZL. Лучше такие операции проводить командами ADIW R24,x (x=0...63).
Код: Выделить всё
LDI R25,HIGH(5638)
LDI R24,LOW(5638)
STS C+0,R25
STS C+1,R24
;
;
;
LDS R25,C+0
LDS R24,C+1
ADIW R24,1
Последний раз редактировалось akl Ср апр 16, 2014 17:01:53, всего редактировалось 1 раз.
через флаг Carry (C) делаются такие штуки. Или вон, как сказал akl, есть специальные команды ADIW, SBIW....
Только dec для работы с 2-байтовым числом использовать нельзя , нужно subi RX,1. Казалось бы - какая разница ? Есть разница. Dec не устанавливает флаг С , поэтму brcs/brcc - мимо .ИС-пытатель писал(а):через флаг Carry (C) делаются такие штуки. SBIW....
Вот что нагуглил по поводу .dbEngineer_Keen писал(а): Не знаю как в железе (думаю что поддерживается), но в симуляторах работает.Код: Выделить всё
.org 0 .db 0xFD,0xCF ;аналог RJMP на 1 адрес вниз .org 0x1FFE .db 0x01,0xC0 ;аналог RJMP на 1 адрес вверх
И практически ничего не понял.. Или к Вашему коду это не имеет отношения и Вы как-то по другому используете директиву?DB - определить байт(ы) в программной памяти или в EEPROM
Директива DB резервирует ресурсы памяти в программной памяти или в EEPROM. Директиве должна предшествовать метка. DB задает список выражений, и должна содержать по крайней мере одно выражение. Размещать директиву следует в сегменте кодов или в EEPROM сегменте.
Список выражений представляет собой последовательность выражений, разделенных запятыми. Каждое выражение должно быть величиной между –128 и 255.
Если директива указывается в сегменте кодов и список выражений содержит более двух величин, то выражения будут записаны так, что 2 байта будут размещаться в каждом слове Flash-памяти.
Синтаксис:
LABEL: .DB список выражений
Пример:
.CSEG
consts: .DB 0, 255, 0b01010101, -128, 0xaa
.ESEG
const2: .DB 1,2,3
Директива использована для вставки машинного кода в текст программы, чтобы компилятор схавал.И практически ничего не понял.. Или к Вашему коду это не имеет отношения и Вы как-то по другому используете директиву?
Директивой он записывает байты память программ. Эти байты не отделены jmp-ми. т.е. по сути это не переменные какие-то или константы, а самые натуральные команды процессору. Причем, обратите внимание, байты записаны по два (слово) и в обратном порядке (сначала младший, потом старший).
З.Ы. Ищите в инете тему "машинный код"
З.Ы. Ищите в инете тему "машинный код"
Директива эта проста до безобразия, она просто говорит компилятору: "хочу в этом месте вставить ЭТИ байты" причем, это не описано в документации но память программ адресуется словами, поэтому нечетное количество байт в СТРОКЕ будет выровнено до четного и дано соответствующее предупреждение. А уж как эти байты будут использоваться в конкретном месте... уже не помню где я видел, но для x86 процессоров был такой прикол - исполняемый файл в виде осмысленной стоки текста, на самом деле это были инструкции процессору - все зависит от того как и чем интерпретировать данные.
А как, допустим, вставить целый файл в текст программы? наподобие типа там .incbin "*.*". Есть что-то такое или нет?
А что из себя файл представляет? И что вы хотите получить в итоге?
.include "file.asm" например. Только файл должен быть правильный чтобы компилятор не ругался
.include "file.asm" например. Только файл должен быть правильный чтобы компилятор не ругался
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
C "file.asm" понятно, его компилятор вставляет как часть текста проги, а мне нужна именно бинарная вставка, т.е. такая директива, которая предполагает вставку абсолютно любого файла в любом формате, как просто блок данных и компилятору должно быть пофиг, что содержит файл. Например как в Easy68k:
Спойлер
Код: Выделить всё
; Processor: 68302
; Target Assembler: 680x0 Assembler in MRI compatible mode
;=========
; segment "ROM"
include "mc68302def.x68"
CLK equ 15000000 System clock Hz
stack equ $d90 Stack pointer
V_gimr equ %101<<V5 V7-V5 in GIMR register
I_vect equ (V_gimr+ISCC3)*4 Interrupt Vector for SCC3
stktemp equ END_SYS_RAM Stack pointer
MEMORY ROM $000000,$200000
org $0 start at the beginning
incbin "GS7000.bin"
ORG $0
off_000 dc.l $0D90
off_004 dc.l START
dcb.l $3A,$80082E
off_0F0 dc.l 0,0,0,0
dcb.l $C0,$80082E
Такой директивы нет, но... все можно обойти! Пишется утилита(на турбопаскале, бейсике), которая конвертирует двоичный файл в текстовый с HEX-кодами и директивами .DW в каждой строке и делов. Если надо каждую перекомпиляцию чтобы коды обновлялись - вставить вызов в скрипт выполнения действий до компиляции. И делов. Я когда-то подобную программу делал для псевдоязыка которая генерировала правильно оформленные двоичные инклуды.
Иманно !Alexeyslav писал(а):Пишется утилита(на турбопаскале, бейсике), которая конвертирует двоичный файл в текстовый с HEX-кодами и директивами .DW в каждой строке и делов.
Привет, коты! 
Такое вот дело, я попробовал использовать регистр чисто для флагов. Получилось очень даже здорово (чего я раньше не додумался?). Но учитывая что в байте 8 бит, было бы здорово для удобства и быстроты все эти биты как-нибудь назвать.
Я полез в inc файл, чтобы посмотреть, как это сделано с регистрами конфигурации МК. Первый бит, который мне пришёл в голову - RXC для UARTа. Написал его в поиск и увидел такую штуку:
Дальше я решил поискать R25 (у меня он в программе используется как статусный), но нашлось только вот это:
Вот у меня вопрос, как-то можно через этот файл назвать биты регистра общего назначения, чтобы потом удобнее было с ними работать?
Такое вот дело, я попробовал использовать регистр чисто для флагов. Получилось очень даже здорово (чего я раньше не додумался?). Но учитывая что в байте 8 бит, было бы здорово для удобства и быстроты все эти биты как-нибудь назвать.
Я полез в inc файл, чтобы посмотреть, как это сделано с регистрами конфигурации МК. Первый бит, который мне пришёл в голову - RXC для UARTа. Написал его в поиск и увидел такую штуку:
Код: Выделить всё
; UCSR0A - USART Control and Status Register A
.equ MPCM0 = 0 ; Multi-processor Communication Mode
.equ U2X0 = 1 ; Double the USART transmission speed
.equ UPE0 = 2 ; Parity Error
.equ DOR0 = 3 ; Data overRun
.equ FE0 = 4 ; Framing Error
.equ UDRE0 = 5 ; USART Data Register Empty
.equ TXC0 = 6 ; USART Transmitt Complete
.equ RXC0 = 7 ; USART Receive Complete
Код: Выделить всё
; GPIOR2 - General Purpose I/O Register 2
.equ GPIOR20 = 0 ;
.equ GPIOR21 = 1 ;
.equ GPIOR22 = 2 ;
.equ GPIOR23 = 3 ;
.equ GPIOR24 = 4 ;
.equ GPIOR25 = 5 ;
.equ GPIOR26 = 6 ;
.equ GPIOR27 = 7 ;
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Потому что хочу научиться.
Только inc-файл не трогайте. Обзывайте эти биты как хотите или в главном файле (в начале кода) или в любом другом самописном файле, подключенном к проекту. Я например все определения и константы всегда выношу в отдельный файл, там гораздо удобнее и править.
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)


