Professor 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Суть вопроса состоит в том чтоб в асемблерной вставке обратится к масиву чисел и одно из чисел извлечь.... Массив должен быть описан как 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 Заранее благодарю за помощь..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба А где обозначен сам массив из которого нужно извлекать число? И какой смысл для такой простой операции вызывать функию, да еще и ассемблерную? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Professor 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба А где обозначен сам массив из которого нужно извлекать число? И какой смысл для такой простой операции вызывать функию, да еще и ассемблерную? Суть вопроса в том что етот кусочек кода надо сделать максимально оптимизированным по скорости.... В самой функции будьт еще другой код... но это уже не важно... с остальным кодом вопросов нет... А где именно обозначить этот массив для решени проблеммы не имет никакого значения... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Ух как давно я не писал для 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 0 16 мая, 2006 Опубликовано 16 мая, 2006 (изменено) · Жалоба Ух как давно я не писал для 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. А где и как описать сам масив если массив расположен во флеше??? Изменено 16 мая, 2006 пользователем Professor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Чё-то я намудрил немного. Вобщем так. Если указатель загружается в пару ZH:ZL то далее указывается ld Rx,Z или ld Rx,Z+. А если пара YH:YL то ld Rx,Y или ld Rx,Y+. А ещё можно через пару XH:XL и команду ld Rx,X или ld Rx,X+. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Professor 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Чё-то я намудрил немного. Вобщем так. Если указатель загружается в пару ZH:ZL то далее указывается ld Rx,Z или ld Rx,Z+. А если пара YH:YL то ld Rx,Y или ld Rx,Y+. А ещё можно через пару XH:XL и команду ld Rx,X или ld Rx,X+. А где и как описать сам масив если массив расположен во флеше??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Ну блин так и писали бы в начале. Я-то думал, что у вас сишный проект с асмовской вставкой и массив уже описан в си-файле. Значит так: 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Professor 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба set_int: ; (в этом месте и надо обратится и извлечЬ число из масива) ldi ZL,LOW(LightTabl*2) ldi ZH,HIGH(LightTabl*2) ; тут добавляете к паре ZH:ZL нужное смещение lpm ; или lpm Rx,Z+ , где Rx - любой регистр, и можно Z, Z+ END set_int А если надо извлечь не один из эелементов массива а один раз к примеру нулевой а вдругой раз первый как вызывать элемент массива в таком случае(когда номер извлекаемого элемента массива всегда меняется)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба А если надо извлечь не один из эелементов массива а один раз к примеру нулевой а вдругой раз первый как вызывать элемент массива в таком случае(когда номер извлекаемого элемента массива всегда меняется)? Я же написал ремарку - "тут добавляете к паре ZH:ZL нужное смещение". Вы можете добавить к паре ZH,ZL любое нужное число - смещение в байтах от начала таблицы. Откуда вы его будете брать - ваши дела. А после того, как добавите, выполняете команду LPM. Ну и с результатом делаете что хотите. Судя по прототипу процедуры, возвращать его не нужно. Можете извлекать хоть десять чисел подряд. Если ещё не понятно, то уточните заодно тип проца. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Professor 0 16 мая, 2006 Опубликовано 16 мая, 2006 (изменено) · Жалоба "тут добавляете к паре ZH:ZL нужное смещение" А добавлять смещение таким образом: add ZL, rx add ZH, rx где rx регистр в котором храниться номер извлекаемого эелемента.... ???? ПРОЦ ATmega16 Изменено 16 мая, 2006 пользователем Professor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Блин, да вы вообще в асме ни бум-бум. Во-первых, добавлять надо так: add ZL, r0 adc ZH, r1 то есть с переносом. Откуда взять r1:r0 ? Зависит от вас. Можете передавать из си-шного кода в качестве параметра процедуры. Можете объявить глобальную переменную WORD в RAM, в сишном коде её менять, а в асмовом читать и использовать в качестве индекса. Можете и читать и изменять только в асмовом файле. Вариантов до кучи. Пока вы не опишите в одном посте сразу все требования к логике работы процедуры общаться так отрывками смысла нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vet 0 16 мая, 2006 Опубликовано 16 мая, 2006 · Жалоба Хинт: вместо add/adc оптимальнее применять subi/sbci, чтобы обойтись без лишних загрузок. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bill 0 18 мая, 2006 Опубликовано 18 мая, 2006 · Жалоба Суть вопроса состоит в том чтоб в асемблерной вставке обратится к масиву чисел и одно из чисел извлечь.... Массив должен быть описан как unsigned char... Как его правильно описать и как его вызывать в асемблерной вставке.... Выдумываете себе проблемы, чтобы потом с успехом их преодолевать? Зачем вообще нужны ассемблерные вставки? Это и некрасиво, и неэффективно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 19 мая, 2006 Опубликовано 19 мая, 2006 · Жалоба самый эффективный способ: 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]; } } Ставишь галочку "генерить ассемблерный файл" в опцияк компилятора на вкладке листинг, компилишь, внимательно изучаешь полученную "рыбу". Или пишешь нужную функцию полностью на С, компилишь, получаешь ассемблерный исходник и его оптимизируешь. Только не забудь прочитать в документации какие регистры функция может портить, а какие должна сохранять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться