|
|
  |
Как в асемблерной вставке обратится к масиву?, Компилятор Embedded Workbench 2.3 |
|
|
|
May 16 2006, 18:07
|
Участник

Группа: Новичок
Сообщений: 35
Регистрация: 12-05-06
Из: Украина Харьков
Пользователь №: 17 045

|
Суть вопроса состоит в том чтоб в асемблерной вставке обратится к масиву чисел и одно из чисел извлечь.... Массив должен быть описан как unsigned char... Как его правильно описать и как его вызывать в асемблерной вставке....
Вставка организованна таким образом:
В main.c:
extern void set_int(void);
void main(void){ set_int(); }
В Text file.asm:
NAME set_int #include <iom16.h> PUBLIC set_int RSEG CODE
set_int:
; (в этом месте и надо обратится и извлеч число из масива)
ret END set_int
Заранее благодарю за помощь.....
|
|
|
|
|
May 16 2006, 18:21
|
Участник

Группа: Новичок
Сообщений: 35
Регистрация: 12-05-06
Из: Украина Харьков
Пользователь №: 17 045

|
Цитата(rezident @ May 16 2006, 21:15)  А где обозначен сам массив из которого нужно извлекать число? И какой смысл для такой простой операции вызывать функию, да еще и ассемблерную? Суть вопроса в том что етот кусочек кода надо сделать максимально оптимизированным по скорости.... В самой функции будьт еще другой код... но это уже не важно... с остальным кодом вопросов нет... А где именно обозначить этот массив для решени проблеммы не имет никакого значения...
|
|
|
|
|
May 16 2006, 18:31
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Ух как давно я не писал для AVR!
NAME set_int #include <iom16.h> PUBLIC set_int RSEG CODE EXTERN chartabl
set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(chartabl) ldi ZH,HIGH(chartabl) ld r0,Y ; или ld r0,Y+ если нужно с инкрементом
ret END set_int _______________________ Это если массив расположен в RAM. А если во флэше, то так:
NAME set_int #include <iom16.h> PUBLIC set_int RSEG CODE EXTERN chartabl
set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(chartabl*2) ldi ZH,HIGH(chartabl*2) lpm ; или lpm rx,z+ , где rx - любой регистр, и можно z, z+, y, y+ ret END set_int
хотя могу ошибаться на счёт умножения на 2. Я это делал когда метка находилась в этом же ASM-файле. Глобальный адрес может уже быть умножен на 2.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 16 2006, 18:37
|
Участник

Группа: Новичок
Сообщений: 35
Регистрация: 12-05-06
Из: Украина Харьков
Пользователь №: 17 045

|
Цитата(GetSmart @ May 16 2006, 21:31)  Ух как давно я не писал для AVR!
NAME set_int #include <iom16.h> PUBLIC set_int RSEG CODE EXTERN chartabl
set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(chartabl) ldi ZH,HIGH(chartabl) ld r0,Y ; или ld r0,Y+ если нужно с инкрементом
ret END set_int _______________________ Это если массив расположен в RAM. А если во флэше, то так:
NAME set_int #include <iom16.h> PUBLIC set_int RSEG CODE EXTERN chartabl
set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(chartabl*2) ldi ZH,HIGH(chartabl*2) lpm ; или lpm rx,z+ , где rx - любой регистр, и можно z, z+, y, y+ ret END set_int
хотя могу ошибаться на счёт умножения на 2. Я это делал когда метка находилась в этом же ASM-файле. Глобальный адрес может уже быть умножен на 2. А где и как описать сам масив если массив расположен во флеше???
Сообщение отредактировал Professor - May 16 2006, 18:38
|
|
|
|
|
May 16 2006, 18:40
|
Участник

Группа: Новичок
Сообщений: 35
Регистрация: 12-05-06
Из: Украина Харьков
Пользователь №: 17 045

|
Цитата(GetSmart @ May 16 2006, 21:38)  Чё-то я намудрил немного. Вобщем так. Если указатель загружается в пару ZH:ZL то далее указывается ld Rx,Z или ld Rx,Z+. А если пара YH:YL то ld Rx,Y или ld Rx,Y+. А ещё можно через пару XH:XL и команду ld Rx,X или ld Rx,X+. А где и как описать сам масив если массив расположен во флеше???
|
|
|
|
|
May 16 2006, 18:46
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Ну блин так и писали бы в начале. Я-то думал, что у вас сишный проект с асмовской вставкой и массив уже описан в си-файле. Значит так:
NAME set_int #include <iom16.h> PUBLIC set_int RSEG CODE
set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(LightTabl*2) ldi ZH,HIGH(LightTabl*2) ; тут добавляете к паре ZH:ZL нужное смещение lpm ; или lpm Rx,Z+ , где Rx - любой регистр, и можно Z, Z+ ret ; возвращаемый результат в регистре Rx
LightTabl: .db 255,250,245,240,234,229,225,220,215,210,206,201,197,193,188,184 .db 180,176,172,169,165,161,158,154,151,147,144,141,138,134,131,128 .db 125,123,120,117,114,111,109,106,104,101,99,96,94,92,90,87
END set_int
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 16 2006, 19:14
|
Участник

Группа: Новичок
Сообщений: 35
Регистрация: 12-05-06
Из: Украина Харьков
Пользователь №: 17 045

|
set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(LightTabl*2) ldi ZH,HIGH(LightTabl*2) ; тут добавляете к паре ZH:ZL нужное смещение lpm ; или lpm Rx,Z+ , где Rx - любой регистр, и можно Z, Z+
END set_int [/quote]
А если надо извлечь не один из эелементов массива а один раз к примеру нулевой а вдругой раз первый как вызывать элемент массива в таком случае(когда номер извлекаемого элемента массива всегда меняется)?
|
|
|
|
|
May 16 2006, 19:28
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата А если надо извлечь не один из эелементов массива а один раз к примеру нулевой а вдругой раз первый как вызывать элемент массива в таком случае(когда номер извлекаемого элемента массива всегда меняется)? Я же написал ремарку - "тут добавляете к паре ZH:ZL нужное смещение". Вы можете добавить к паре ZH,ZL любое нужное число - смещение в байтах от начала таблицы. Откуда вы его будете брать - ваши дела. А после того, как добавите, выполняете команду LPM. Ну и с результатом делаете что хотите. Судя по прототипу процедуры, возвращать его не нужно. Можете извлекать хоть десять чисел подряд. Если ещё не понятно, то уточните заодно тип проца.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
May 16 2006, 19:50
|
Участник

Группа: Новичок
Сообщений: 35
Регистрация: 12-05-06
Из: Украина Харьков
Пользователь №: 17 045

|
Цитата(GetSmart @ May 16 2006, 22:28)  "тут добавляете к паре ZH:ZL нужное смещение" А добавлять смещение таким образом: add ZL, rx add ZH, rx где rx регистр в котором храниться номер извлекаемого эелемента.... ???? ПРОЦ ATmega16
Сообщение отредактировал Professor - May 16 2006, 20:03
|
|
|
|
|
May 18 2006, 11:18
|
Местный
  
Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219

|
Цитата(Professor @ May 16 2006, 21:07)  Суть вопроса состоит в том чтоб в асемблерной вставке обратится к масиву чисел и одно из чисел извлечь.... Массив должен быть описан как unsigned char... Как его правильно описать и как его вызывать в асемблерной вставке.... Выдумываете себе проблемы, чтобы потом с успехом их преодолевать? Зачем вообще нужны ассемблерные вставки? Это и некрасиво, и неэффективно.
|
|
|
|
|
May 19 2006, 13:23
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
самый эффективный способ: main.c Код #include <stdint.h>
uint8_t const __flash Array[8] = {1,2,3,4,5,6,7,8};
extern void AsmFunc(void); void main (void) { AsmFunc(); } Asm_fish.c: Код #include <stdint.h> extern uint8_t const __flash Array[8]; uint8_t Tmp; void AsmFunc(void) { uint8_t i; for(i = 0; i < 3; i++) { Tmp = Array[i*2]; } } Ставишь галочку "генерить ассемблерный файл" в опцияк компилятора на вкладке листинг, компилишь, внимательно изучаешь полученную "рыбу". Или пишешь нужную функцию полностью на С, компилишь, получаешь ассемблерный исходник и его оптимизируешь. Только не забудь прочитать в документации какие регистры функция может портить, а какие должна сохранять.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0
|
|
|