|
Вопрос к ассемблерщикам, Автоматическая растановка адресов |
|
|
|
Mar 2 2009, 09:17
|
Группа: Новичок
Сообщений: 11
Регистрация: 16-02-09
Пользователь №: 44 925

|
Пример: .equ Napruga = SRAM_START+123 Таких директив может быть сотня и более. Иногда возникает необходимость вставить посередине новую директиву или расширить массив. Из-за этого возникают проблемы, что нужно менять адресацию. Приходиться много править. Существуют ли какие-нибудь методы или вспомогательные программы позволяющие решить данную проблему?
|
|
|
|
|
Mar 2 2009, 10:00
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(_Алексей_ @ Mar 2 2009, 12:17)  Пример: .equ Napruga = SRAM_START+123 Таких директив может быть сотня и более. Почему-то все (без исключения!) программисты, которых я встречал, счтали, что они знают язык ассемблера на том основании, что они знают систему команд и их мнемоники. Некоторые знали директиву equ, а многие даже ее не знали, а распределяли память данных вручную, на листочке, а в программу вбивали готовые числа. О том, чтобы объявлять какие-то там сегменты, они слышали лишь краем уха, сами конечно же никогда этого не делали.
|
|
|
|
|
Mar 2 2009, 13:22
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(_Pasha @ Mar 2 2009, 14:08)   Но и AVRASM тоже хорош - тупой как пробка. Невозможно никаким макаком описАть структуру, кроме .equ, макросредства - ваще молчу. Тоже поддерживаю. По сравнению с тем ассемблером, которым я пользовался для 8051 - это большой скачёк назад.  Некоторые моменты отображу. Код ;----------------------------------------------------------------------------- .equ inline = portd2;(INT0) вход с цифровой линии(_/~~\______/~~~~\______) ;----------------------------------------------------------------------------- .equ DTR = portd4; Готовность компьютера .equ portDTR = portd .equ pinDTR = pind .equ ddrDTR = ddrd .equ RTS = portd3; Запрос передачи компьютера .equ portRTS = portd .equ pinRTS = pind .equ ddrRTS = ddrd Код .def flg2 = r17;регистр битовых признаков No 2 .equ bline = 0 ; новая команда от MODEMLN .equ ctrll = 1 ; команда (не данные) от MODEMLN .equ ctrlh = 2 ; команда (не данные) от MODEMH .equ bnocar = 3 ; Пропала несущая .equ blast = 4 ; Выполняется комманда ComL (offline) .equ bonline = 5 ; Бит признака режима (1-online) .equ blnint = 6 ; наличие импульса в телефонной линии (1) .equ bautob = 7 ; запретить AUTOBOD (0-запретить)
.def outdata = r18;текущий байт данных в телефонную линию Код ..equ lBuf = $1cf; Длина буферов 463 байта
.dseg .if chip == 88 .org $0100; для ATMEGA88 .else .org $060; для ATMEGA8 .endif
digit: .byte 1;регистр данных текущей набираемой цифры номера
s0: .byte 1; число звонков необходимых для автоответа s1: .byte 1; счётчик звонков s2: .byte 1; + s3: .byte 1; cr s4: .byte 1; lf s5: .byte 1; забой s6: .byte 1; число сек. ожидания при "слепом наборе" без dial tone s7: .byte 1; ожидание несущей s8: .byte 1; время в 0.1 сек на "," s9: .byte 1; время в десят. долях сек. установки соед. s10: .byte 1; ячейка пользователя Кстати ассемблер IAR для AVR когда-то был свободно распространяемый. Правда не знаю как с интеграцией его в AVR Studio дела абстоят. В общем и целом - перешёл на Си и жутко жалею, что не сделал этого лет эдак на 5 раньше.
|
|
|
|
|
Mar 2 2009, 17:27
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(_Алексей_ @ Mar 2 2009, 16:17)  Иногда возникает необходимость вставить посередине новую директиву или расширить массив. Из-за этого возникают проблемы, что нужно менять адресацию. Приходиться много править. А вот так - древний способ - Код .equ SRAM_START = 0x0000; .equ SRAM_NEXT_1 = SRAM_START + 1; .equ SRAM_NEXT_2 = SRAM_NEXT_1 + 10; .equ SRAM_NEXT_3 = SRAM_NEXT_2 + 100; И директив может быть сотня и более.  А чтобы что то вставить приходится поправить всего-то пару строк.
--------------------
|
|
|
|
|
Mar 3 2009, 07:32
|
Группа: Новичок
Сообщений: 11
Регистрация: 16-02-09
Пользователь №: 44 925

|
>Почитайте описание на ассемблер, там это есть.
Действительно. Даже как-то стыдно стало за свой вопрос.
|
|
|
|
|
Mar 8 2009, 06:50
|
Местный
  
Группа: Свой
Сообщений: 303
Регистрация: 3-03-05
Пользователь №: 3 044

|
Цитата(_Алексей_ @ Mar 2 2009, 13:17)  ... Иногда возникает необходимость вставить посередине новую директиву или расширить массив. Из-за этого возникают проблемы, что нужно менять адресацию. Приходиться много править. ...... Если не хочется чего - не то делать - надо подумать, как этого не делать. Код .dseg
.org ... (если очень хочется, но мне не разу не понадобилось. Опять потом искать и менять)
dRcvdBuf:;начало буфера (например, приема) dRcvdLen: .byte 1 dRcvdAdr: .byte 2 dRcvdTime: .byte 4 dRcvdName: .byte 20 dRcvdErrors: .byte 1 dRcvdVolts: .byte 2 dRcvdBufEnd:;это что бы следить за концом буфера ;И вставляй, что хочешь, само настроиться ;что бы привязать к началу буфера (для использоввания указателей и поддержания одинакового смещения в разных программах) можно посчитать смещения от начала буфера Код .equ shRcvdLen=dRcvdLen-dRcvdBuf .equ shRcvdAdr=dRcvdAdr-dRcvdBuf ;.................................................... .equ cRcvdBufLen=dRcvdBufE-dRcvdBuf;длина буфера
ldd rTmp,z+shRcvdLen ;Можно макрос написать: Код .macro mac_BufSet @0: .byte @2 .equ @1=@0-BufStart .endm ;------------------------------- .dseg dRcvdBuf: .set BufStart=dRcvdBuf
mac_BufSet dRcvdLen,shRcvdLen,1 mac_BufSet dRcvdAdr,shRcvdAdr,2 mac_BufSet dRcvdTime,shRcvdTime,4 mac_BufSet dRcvdName,shRcvdName,20 ................... dRcvdBufEnd: Как и на зеркало, не стоит на ассемблер пенять раньше времени. Там еще препроцессор есть. Весьма удобная вещь, если научиться. P.S. Пришла по дороге идея, но прямо сейчас не на чем проверить: Код macro mac_BufSet d@0: .byte @1 .equ sh@0=d@0-BufStart .endm
mac_BufSet RcvdLen,1 mac_BufSet RcvdAdr,2 Еще меньше писанины
--------------------
Опыт - чудесная вещь: легко использовать, можно продать, трудно пропить.
|
|
|
|
|
Mar 8 2009, 07:10
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(CDT @ Mar 8 2009, 09:50)  ;Можно макрос написать: Код .macro mac_BufSet @0: .byte @2 .equ @1=@0-BufStart .endm ;------------------------------- Для того чтобы что-то советовать, желательно хотя бы раз самому поробовать это применить. И вот когда Вы увидите в ответ на желание создать такой макрос, вот это Цитата error: .byte directive illegal in macro definition Я думаю, у Вас возникнет острое желание извиниться за ту чушь, которую Вы написали.
|
|
|
|
|
Mar 8 2009, 07:45
|
Знающий
   
Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640

|
Цитата(_Pasha @ Mar 8 2009, 10:10)  Для того чтобы что-то советовать, желательно хотя бы раз самому поробовать это применить. +1 А я вот не совсем по теме, но то, что всегда применяю. Тоже про доступ к данным. Чаще всего приходится использовать таблицы в FLASH или ОЗУ размером до 256 байт или слов. В регистре находится N элемента (индекс массива) и к этому N нужно прибавить адрес начала массива. А массив не выровнен, т.е. может переходить через границу 256. Т.е. старший байт адреса может отличаться на 1. Стандартный способ это 4 такта. Но есть способ лучше. Я написал макро, и всегда и использую. Код .MACRO TAB_Z subi ZL,low(-low(@0)); получение sbc ZH,ZH ; адреса в subi ZH,low(-high((@0)-1))-1; таблице .ENDMACRO Перед вызовом смещение д.б. в ZL. Параметр в этой макрокоманде - адрес начала таблицы. В байтах если это данные, в словах если это таблица переходов. Такие макрокоманды у меня обычно и для Y и для X описаны. Рекомендую...
|
|
|
|
|
Mar 9 2009, 06:15
|
Местный
  
Группа: Свой
Сообщений: 303
Регистрация: 3-03-05
Пользователь №: 3 044

|
Цитата(_Pasha @ Mar 8 2009, 11:10)  Что ж так нервничать. Можно было бы и предложить правильное решение. Я сразу предупредил, что обкатать не на чем было. И что думать надо говорил. Сейчас есть на чем обкатать. Вот то, что работает. Код ;задает: dX-мл. адр. блока ячеек, shX-смещение от начала буфера, cX- длина данного блока ячеек ;Y - число выделяемых ячеек .macro mac_BufSet;X,Y .equ d@0=BufNext .equ sh@0=d@0-BufStart .equ c@0=@1 .set BufNext=BufNext+@1 .endm ;------------------------------- .dseg
.equ cRcvdNameLen=20
dRcvdBuf: .set BufStart=dRcvdBuf;задаем начало определяемого буфера .set BufNext=dRcvdBuf
mac_BufSet RcvdLen,1 mac_BufSet RcvdAdr,2 mac_BufSet RcvdTime,4 mac_BufSet RcvdName, cRcvdNameLen
.equ dRcvdBufEnd=BufNext ;задаем конец определяемого буфера .byte dRcvdBufEnd-dRcvdBuf;резервируем ОЗУ под определяемый буфер
.cseg Интересно, что работают конструкции типа: Код .equ c@0Long=@1;добавляет к базовой метке "с" и "Long" .equ @0@2=@1;собирает в одну метку 0-й и 2-й параметр макроса Можно и еще чего по вычислять, зависимое от этих определений. А кто еще чего полезного предложит?
--------------------
Опыт - чудесная вещь: легко использовать, можно продать, трудно пропить.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|