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

|
Пример: .equ Napruga = SRAM_START+123 Таких директив может быть сотня и более. Иногда возникает необходимость вставить посередине новую директиву или расширить массив. Из-за этого возникают проблемы, что нужно менять адресацию. Приходиться много править. Существуют ли какие-нибудь методы или вспомогательные программы позволяющие решить данную проблему?
|
|
|
|
|
 |
Ответов
|
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 11 2009, 08:46
|
Участник

Группа: Новичок
Сообщений: 24
Регистрация: 20-10-06
Пользователь №: 21 500

|
Цитата(galjoen @ Mar 8 2009, 13:45)  ... Код .MACRO TAB_Z subi ZL,low(-low(@0)); получение sbc ZH,ZH; адреса в subi ZH,low(-high((@0)-1))-1; таблице .ENDMACRO ... Спасибо за интересный ход, ибо ситуация действительно частая. Сам долгое время работал с ассемблером, но в последнее время, ввиду объемности проектов, пользуюсь связкой eclipse+gcc (последняя сборка от Klen'а), однако по-прежнему, в критических местах люблю подписать на асме. попытка внедрить этот код увенчалась провалом - никак компилятор сожрать не может такую конструкцию Код "subi %A[queue],-lo8(%[heap])" "\n\t" /*получение*/ "sbc %B[queue],%B[queue]" "\n\t" /*адреса в*/ "subi %B[queue],lo8(-hi8(%[heap]-1)-1)" "\n\t" /*таблице*/ ошибки выдает дурные C:\DOCUME~1\electro\LOCALS~1\Temp/ccX8y7d0.s:1163: Error: garbage at end of line C:\DOCUME~1\electro\LOCALS~1\Temp/ccX8y7d0.s:1165: Error: `)' required C:\DOCUME~1\electro\LOCALS~1\Temp/ccX8y7d0.s:1165: Error: garbage at end of line судя по всему не может выполнять арифметические операции потому как простейшие конструкции типа Код "subi %A[queue],lo8(%[heap])" "\n\t" /*получение*/ "subi %B[queue],hi8(%[heap])" "\n\t" /*таблице*/ или "subi %A[queue],%A[heap]" "\n\t" /*получение*/ "subi %B[queue],%B[heap]" "\n\t" /*таблице*/ скармливаются успешно чуть более подробный код для введения в курс дела: CODE struct { uint8_t Put; uint8_t Get; MPACKET* Container[CONST_FREEMEM_QUEUE_SIZE]; }QueueFreePacket;
исходный код на С void QueuePut(TQUEUE* Queue,MPACKET* Packet){ if (Packet){ if(Queue){ //uint8_t tmp=Queue->Put + 1; //if(tmp==CONST_QUEUE_SIZE)tmp=0;
uint8_t tmp=Queue->Put - (CONST_QUEUE_SIZE-1); if(tmp)tmp+=CONST_QUEUE_SIZE;
if (tmp!=Queue->Get){ Queue->Container[Queue->Put]=Packet; Queue->Put=tmp; return; } } QueueFreePacket.Container[QueueFreePacket.Put++]=Packet; if (QueueFreePacket.Put==CONST_FREEMEM_QUEUE_SIZE) QueueFreePacket.Put=0; } }
часть асемблерной вставки для помещения пакета в очередь свободных пакетов __asm__ __volatile__( ..... "pkt_move_to_heap%=:" "\n\t" "lds %A[queue],%[heap]" "\n\t" "mov %[tmp],%A[queue]" "\n\t" "subi %A[queue],-lo8(%[heap])" "\n\t" /*получение*/ "sbc %B[queue],%B[queue]" "\n\t" /*адреса в*/ "subi %B[queue],lo8(-hi8(%[heap]-1)-1)" "\n\t" /*таблице*/ "st %a[queue]+,%A[pkt]" "\n\t" "st %a[queue],%B[pkt]" "\n\t" "subi %[tmp],(%[heap_size]-1)<<1" "\n\t" "cpse %[tmp],__zero_reg__" "\n\t" "subi %[tmp],-(%[size]<<1)" "\n\t" "sts %[heap],%[tmp]" "\n\t"
"exit%=:" "\n\t" : "=&d"(tmp) : [queue]"b"(Queue),[pkt]"w"(Packet),[tmp]"r"(tmp),[size]"M"(CONST_QUEUE_SIZE),[heap]"m"(QueueFreePacket),[heap_size]"M"(CONST_FREEMEM_QUEUE_SIZE) : "1","memory" );
Подскажите как коректно переписать это место ассемблерной вставки
Сообщение отредактировал yod - Mar 11 2009, 08:49
|
|
|
|
|
Mar 14 2009, 10:02
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(galjoen @ Mar 8 2009, 09:45)  А массив не выровнен, т.е. может переходить через границу 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 8 2009, 11:52)  Красиво! Спасибо, записал на корочку. Цитата(_Pasha @ Mar 8 2009, 12:04)  Респект! А говорят, что про асм и AVR уже все известно... А-а-а-а!!!! Мужики, что вы делаете? Я на собственной шкуре убедился в реальности тех психологических экспериментов, когда садят человека в компании, как он думает, таких же испытуемых, задают всем несколько вопросов, а потом показывают белый листик и спрашивают "какой цвет?" все говорят "чёрный", доходят до испытуемого, он мучается, перекашивается лицом, но говорит "чёрный". Сначала я пожал плечами. Хотел уже написать в форум. Потом решил, что вечер и я чего-то не соображаю. Долго не мог понять, о каких четырёх тактах речь, если мы говорим об ассемблерном коде, а не том, что генерит gcc. Даже скопировал этот макрос в файл, чтобы утром разобраться. В не очень хорошем состоянии сейчас, так и утром тоже тупил довольно долго (мучался и перекашивался лицом ;-) ). Никаких фокусов с sbc и сложными выражениями тут не надо. Код .MACRO TAB_Z clr ZH subi ZL, low( -@0 ) sbci ZH, high( -@0 ) .ENDMACRO Цитата(yod @ Mar 11 2009, 10:46)  Подскажите как коректно переписать это место ассемблерной вставки  Ну теперь, очевидно, так: Код uint8_t table[8];
uint8_t rd(uint8_t index) { return table[index]; }
uint8_t rda(uint8_t index) { uint8_t result; __asm__ __volatile__ ( "clr %B[ptr]" "\n\t" "subi %A[ptr], lo8(-%[tbl])" "\n\t" "subi %B[ptr], hi8(-%[tbl])" "\n\t" "ld %[result], %a[ptr]" : [result]"=r"(result) : [ptr]"e"(index), [tbl]"m"(table[0]) ); return result; } Код rd: ldi r30,lo8(table) ldi r31,hi8(table) add r30,r24 adc r31,__zero_reg__ ld r24,Z clr r25 ret
rda: mov r30,r24 /* #APP */ clr r31 subi r30, lo8(-table) subi r31, hi8(-table) ld r24, Z /* #NOAPP */ clr r25 ret upd: Тю, gcc генерит то, что надо, а ассемблер потом ругается. upd2: Ещё одни скобки нужны, без них он путается в том, от какого нуля нужно онять tbl для получения -tblЦитата "subi %A[ptr], lo8(-(%[tbl]))" "\n\t" "subi %B[ptr], hi8(-(%[tbl]))" "\n\t" Так линкуется и дизассемблер покзывает что надо. (опять туплю - пока не полез в свой же рабочий асмовый исходник - не вспомнил... как бы это выспаться...)
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
Сообщений в этой теме
_Алексей_ Вопрос к ассемблерщикам Mar 2 2009, 09:17 bbill Самый удобный способ, резервирование памяти, расст... Mar 2 2009, 09:37 777777 Цитата(_Алексей_ @ Mar 2 2009, 12:17) При... Mar 2 2009, 10:00 _Pasha Цитата(777777 @ Mar 2 2009, 14:00) О том... Mar 2 2009, 10:08  SasaVitebsk Цитата(_Pasha @ Mar 2 2009, 14:08) Но и ... Mar 2 2009, 13:22  Сергей Борщ Цитата(_Pasha @ Mar 2 2009, 12:08) Невозм... Mar 3 2009, 08:38 prottoss Цитата(_Алексей_ @ Mar 2 2009, 16:17) Ино... Mar 2 2009, 17:27 _Алексей_ >Почитайте описание на ассемблер, там это есть.... Mar 3 2009, 07:32   Сергей Борщ Цитата(galjoen @ Mar 8 2009, 09:45) Такие... Mar 8 2009, 09:52   _Pasha Цитата(galjoen @ Mar 8 2009, 10:45) Но ес... Mar 8 2009, 10:04    Maik-vs Какое странное и невнятное обсуждение. То есть нек... Mar 8 2009, 15:17     SasaVitebsk Цитата(Maik-vs @ Mar 8 2009, 19:17) ... Mar 9 2009, 21:07      adc Цитата(SasaVitebsk @ Mar 10 2009, 00:07) ... Mar 10 2009, 07:58      Maik-vs Цитата(SasaVitebsk @ Mar 10 2009, 00:07) ... Mar 10 2009, 08:27       SasaVitebsk Цитата(Maik-vs @ Mar 10 2009, 12:27)... Mar 10 2009, 17:34    galjoen Цитата(yod @ Mar 11 2009, 11:46) ...
Подс... Mar 11 2009, 14:53     yod гхм, спасибо, попробовал, не вышло.
теперь пишет и... Mar 11 2009, 18:52      galjoen Цитата(yod @ Mar 11 2009, 21:52) гхм, спа... Mar 11 2009, 19:12       yod при асемблерной вставке сам код предается как стро... Mar 12 2009, 02:02    _Pasha Цитата(yod @ Mar 11 2009, 11:46) Подскажи... Mar 12 2009, 02:34     SasaVitebsk Цитата(ReAl @ Mar 14 2009, 14:02) как бы ... Mar 14 2009, 11:12     galjoen Цитата(ReAl @ Mar 14 2009, 13:02) Никаких... Mar 14 2009, 16:27      ReAl Цитата(galjoen @ Mar 14 2009, 18:27) Для ... Mar 15 2009, 09:00  CDT Цитата(_Pasha @ Mar 8 2009, 11:10)
Что ж... Mar 9 2009, 06:15   _Pasha Цитата(CDT @ Mar 9 2009, 09:15) Что ж так... Mar 10 2009, 08:26
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|