реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Пытаюсь освоить ASM вставку
QuickWitted
сообщение Dec 2 2008, 13:59
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 21-06-07
Из: СНГ
Пользователь №: 28 596



Я основной разработчик и концептор сайта http://www.swordgreenline.narod.ru/
До этого я разрабатывал некоммерческий софт для нашего сайта на асме.

По просьбам пользователей сейчас пробую прикрутить коммуникационный драйвер на СИ.
Т.е.
1 есть рабочий драйвер на СИ
2 есть отлаженная программа на асме
и я хочу объединить их.

на СИ всё переписать нереально - элементарно не влезет...

пишу под ATMega8

с вопросом сборки проекта на си я разобрался...
поставил avr-gcc. Пакет avr-gcc на платформе Windows входит в состав пакета WinAVR.
собираю через Makefile и получаю рабочий хэкс.

Теперь подходим к вопросу как делать вставки на асме в программу СИ

мне нужен массив.
как я понял на СИ массив и переменная его заполненности объявляются так:

#define My_BUFLEN 254
static unsigned short My_buf[My_BUFLEN];
static uchar My_head = 0;

теперь вопрос
1) как правильно объявить асм вставку?
2) из асма обратиться к массиву?
3) можно ли создать процедуру на асме вызываемую с СИ?

на Си в коде есть ещё одна структура

static uchar Buffinput[6] = { 1, 0,0,0,0,0, }

как обратиться к ней на асме?

Как на си объявить обработчик прерывания по переполнению таймера
на асме это выглядит так

.org OVF0addr ; Overflow0 Interrupt Vector adres
rjmp OVF0handler ; Прерывание по переполнению

ниже
OVF0handler:
действие
reti

Сообщение отредактировал QuickWitted - Dec 2 2008, 14:36


--------------------
Сайт с разработками http://www.mindrunway.ru/
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 2 2008, 14:15
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



http://www.ibiblio.org/gferg/ldp/GCC-Inlin...mbly-HOWTO.html
http://www.cs.virginia.edu/~clc5q/gcc-inline-asm.pdf
http://tldp.org/HOWTO/Assembly-HOWTO/gcc.html

А ещё почитайте про avr-gcc ABI
http://www.nongnu.org/avr-libc/user-manual...l#faq_reg_usage
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 2 2008, 14:19
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(QuickWitted @ Dec 2 2008, 16:59) *
Теперь подходим к вопросу как делать вставки на асме в программу СИ

мне нужен массив.
Нет, нужен кусок кода. Массив - это данные.
Цитата
теперь вопрос
1) как правильно объявить асм вставку?
Вставить асм команду в С программу - asm("...")

Цитата
2) из асма обратиться к массиву?
3) можно ли создать процедуру на асме вызываемую с СИ?
Так, тут надо уточнить детали - кусок программы на asm используется как 'черный ящик' (в виде готового hex), или же он компилируется вместе с программой на С ? Если первое, то все взаимодействие придется проводить на уровне голых адресов (т.е. никаких массивов в С), если второе, то можно состыковать и массивы и процедуры, причем в обе стороны.


Цитата
Как на си объявить обработчик прерывания по переполнению таймера
на асме это выглядит так

.org OVF0addr ; Overflow0 Interrupt Vector adres
rjmp OVF0handler ; Прерывание по переполнению
Смотри доки к winavr, какое то ключевое слово (типа __attribute__((interrupt)) или соотвествующий define) у описания функции
Go to the top of the page
 
+Quote Post
QuickWitted
сообщение Dec 2 2008, 14:28
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 21-06-07
Из: СНГ
Пользователь №: 28 596



Цитата(XVR @ Dec 2 2008, 19:19) *
Вставить асм команду в С программу - asm("...")


Мне не команду а кусок обработчика
моей математики...

Цитата(XVR @ Dec 2 2008, 19:19) *
Так, тут надо уточнить детали - кусок программы на asm используется как 'черный ящик' (в виде готового hex), или же он компилируется вместе с программой на С ?


в виде файла асм, который я написал и отладил.
обработчик прерывания, который заполняет массив данными
их пережёвывает, получает хэш, сравнивает по табличке и выдаёт результат в
static uchar Buffinput[6] = { 1, 0,0,0,0,0, }

после драйвер на си занимается их передачей во внешний мир.


--------------------
Сайт с разработками http://www.mindrunway.ru/
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 2 2008, 14:37
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(QuickWitted @ Dec 2 2008, 16:28) *
Мне не команду а кусок обработчика
моей математики...
в виде файла асм, который я написал и отладил.
обработчик прерывания, который заполняет массив данными
их пережёвывает, получает хэш, сравнивает по табличке и выдаёт результат в
static uchar Buffinput[6] = { 1, 0,0,0,0,0, }

после драйвер на си занимается их передачей во внешний мир.

Для того что бы можно было вызвать асм-функцию из с-функции, асм-функция должна соответствовать соглашению о используемых регистрах, которое называется ABI, ссылку приводил. Если же хотите в с-фунцию вставить асм код - читайте про формат inline assembly для gcc, ссылки приводил.
Go to the top of the page
 
+Quote Post
QuickWitted
сообщение Dec 2 2008, 14:38
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 21-06-07
Из: СНГ
Пользователь №: 28 596



Цитата(gotty @ Dec 2 2008, 19:15) *
А ещё почитайте про avr-gcc ABI


И там linux/include/asm-i386/
А мне под ATMega8


--------------------
Сайт с разработками http://www.mindrunway.ru/
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 2 2008, 14:40
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(QuickWitted @ Dec 2 2008, 16:38) *
И там linux/include/asm-i386/
А мне под ATMega8


Цитата(gotty @ Dec 2 2008, 16:15) *
А ещё почитайте про avr-gcc ABI
http://www.nongnu.org/avr-libc/user-manual...l#faq_reg_usage
Go to the top of the page
 
+Quote Post
QuickWitted
сообщение Dec 2 2008, 14:50
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 21-06-07
Из: СНГ
Пользователь №: 28 596



Цитата(gotty @ Dec 2 2008, 19:37) *
Для того что бы можно было вызвать асм-функцию из с-функции, асм-функция должна соответствовать соглашению о используемых регистрах


Брр...
Ты помоему про комповый СИ, а я про WinAVR
и никаких особых соглашений я в примере не видел....

Рабочий пример
/* Register assignments for usbMeasureFrameLength on gcc */
/* Calling conventions on gcc:
* First parameter passed in r24/r25, second in r22/23 and so on.
* Callee must preserve r1-r17, r28/r29
* Result is passed in r24/r25
*/
# define resL r24
# define resH r25
# define cnt16L r24
# define cnt16H r25
# define cntH r26
#endif
# define cnt16 cnt16L

; extern unsigned usbMeasurePacketLength(void);
; returns time between two idle strobes in multiples of 7 CPU clocks
.global usbMeasureFrameLength
usbMeasureFrameLength:
ldi cntH, 6 ; wait ~ 10 ms for D- == 0
clr cnt16L
clr cnt16H
usbMFTime16:
dec cntH
breq usbMFTimeout
usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe)
sbiw cnt16, 1 ;[0] [6]
breq usbMFTime16 ;[2]
sbic USBIN, USBMINUS ;[3]
rjmp usbMFWaitStrobe ;[4]
usbMFWaitIdle: ; then wait until idle again
sbis USBIN, USBMINUS ;1 wait for D- == 1
rjmp usbMFWaitIdle ;2
ldi cnt16L, 1 ;1 represents cycles so far
clr cnt16H ;1
usbMFWaitLoop:
in cntH, USBIN ;[0] [7]
adiw cnt16, 1 ;[1]
breq usbMFTimeout ;[3]
andi cntH, USBMASK ;[4]
brne usbMFWaitLoop ;[5]
usbMFTimeout:
#if resL != cnt16L
mov resL, cnt16L
mov resH, cnt16H
#endif
ret

#undef resL
#undef resH
#undef cnt16
#undef cnt16L
#undef cnt16H
#undef cntH

#endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */


Регистров из примера мне хватит...

вопрос
как обратиться к элементу массива?
как обратиться к элементу структуры из 6 байт?
как обратиться к переменной?

А функцию мне надо без параметров и возвращаемых величин.
просто запустить на исполнение амс код.


--------------------
Сайт с разработками http://www.mindrunway.ru/
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 2 2008, 14:54
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(QuickWitted @ Dec 2 2008, 16:44) *
Брр...
Ты помоему про комповый СИ, а я про WinAVR
и никаких особых соглашений я в примере не видел....

Рабочий пример
/* Register assignments for usbMeasureFrameLength on gcc */
/* Calling conventions on gcc:
* First parameter passed in r24/r25, second in r22/23 and so on.
* Callee must preserve r1-r17, r28/r29
* Result is passed in r24/r25
*/


Разве? Мы наверно просто на разных языках говорим smile.gif ABI = Calling conventions

Цитата
What registers are used by the C compiler?

Data types:
char is 8 bits, int is 16 bits, long is 32 bits, long long is 64 bits, float and double are 32 bits (this is the only supported floating point format), pointers are 16 bits (function pointers are word addresses, to allow addressing up to 128K program memory space). There is a -mint8 option (see Options for the C compiler avr-gcc) to make int 8 bits, but that is not supported by avr-libc and violates C standards (int must be at least 16 bits). It may be removed in a future release.
Call-used registers (r18-r27, r30-r31):
May be allocated by gcc for local data. You may use them freely in assembler subroutines. Calling C subroutines can clobber any of them - the caller is responsible for saving and restoring.
Call-saved registers (r2-r17, r28-r29):
May be allocated by gcc for local data. Calling C subroutines leaves them unchanged. Assembler subroutines are responsible for saving and restoring these registers, if changed. r29:r28 (Y pointer) is used as a frame pointer (points to local data on stack) if necessary. The requirement for the callee to save/preserve the contents of these registers even applies in situations where the compiler assigns them for argument passing.
Fixed registers (r0, r1):
Never allocated by gcc for local data, but often used for fixed purposes:
r0 - temporary register, can be clobbered by any C code (except interrupt handlers which save it), may be used to remember something for a while within one piece of assembler code

r1 - assumed to be always zero in any C code, may be used to remember something for a while within one piece of assembler code, but must then be cleared after use (clr r1). This includes any use of the [f]mul[s[u]] instructions, which return their result in r1:r0. Interrupt handlers save and clear r1 on entry, and restore r1 on exit (in case it was non-zero).

Function call conventions:
Arguments - allocated left to right, r25 to r8. All arguments are aligned to start in even-numbered registers (odd-sized arguments, including char, have one free register above them). This allows making better use of the movw instruction on the enhanced core.
If too many, those that don't fit are passed on the stack.

Return values: 8-bit in r24 (not r25!), 16-bit in r25:r24, up to 32 bits in r22-r25, up to 64 bits in r18-r25. 8-bit return values are zero/sign-extended to 16 bits by the called function (unsigned char is more efficient than signed char - just clr r25). Arguments to functions with variable argument lists (printf etc.) are all passed on stack, and char is extended to int.

Warning:
There was no such alignment before 2000-07-01, including the old patches for gcc-2.95.2. Check your old assembler subroutines, and adjust them accordingly.


GCC - это не компилятор только для AVR, а семейство компиляторов для разных архитектур и языков. По этому документацию иногда приходится адаптировать под свою платформу smile.gif По ссылкам про inline assembly надо было разобраться не в ассемблере, а способе взаимодействия ассемблерных вставок и окружающего С-кода и данных.
Может это будет проще понять http://www.nongnu.org/avr-libc/user-manual/inline_asm.html
Go to the top of the page
 
+Quote Post
QuickWitted
сообщение Dec 2 2008, 15:01
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 21-06-07
Из: СНГ
Пользователь №: 28 596



Цитата(gotty @ Dec 2 2008, 19:54) *
Разве? Мы наверно просто на разных языках говорим smile.gif


Если не трудно - дай пример работы с массивами...
как обратиться с асма...

с утра уже в нете ковыряюсь... с нулевым результатом....

все массивы на си лопатят, а у меня массив и это чудо с 6 переменными...


--------------------
Сайт с разработками http://www.mindrunway.ru/
Go to the top of the page
 
+Quote Post
msalov
сообщение Dec 2 2008, 15:06
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045



Цитата(QuickWitted @ Dec 2 2008, 17:01) *
Если не трудно - дай пример работы с массивами...
как обратиться с асма...


Уж извини, ссылки на то как сделать привёл, а вот делать надо самому wink.gif Да и если честно, с инлайн ассемблером я не на "ты" sad.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 2 2008, 17:50
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(gotty @ Dec 2 2008, 18:06) *
Да и если честно, с инлайн ассемблером я не на "ты" sad.gif

А зачем тут этот самый костыль-inline всовывать-то? Пусть читает правила взаимодейстия, или просто (для особо ленивых) скомлировалась болванка будующей ASM функции и все.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
QuickWitted
сообщение Dec 2 2008, 17:58
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 21-06-07
Из: СНГ
Пользователь №: 28 596



Цитата(zltigo @ Dec 2 2008, 22:50) *
А зачем тут этот самый костыль-inline всовывать-то? Пусть читает правила взаимодейстия, или просто (для особо ленивых) скомлировалась болванка будующей ASM функции и все.


Первое там много и под все платформы
второе - где конкретно написано про доступ к переменным си кода из Асма?

Афоризм: Словом можно обидеть. Словарем - убить.

Сообщение отредактировал QuickWitted - Dec 2 2008, 18:19


--------------------
Сайт с разработками http://www.mindrunway.ru/
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Dec 2 2008, 18:29
Сообщение #14


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(QuickWitted @ Dec 2 2008, 21:58) *
где конкретно написано про доступ к переменным си кода из Асма?

Объявите переменную extern в асмовом файле.
Все объекты в сишном, которые используются в асмовом, должны быть глобальными и volatile
Поля структур размещаются в памяти в порядке их декларации, в т.ч. битовые - с младших битов, с учетом выравнивания по 8 битам в данном случае.
Порядок нумерации элементов массива... забыл, сорри sad.gif
Из асма лучше не вызывать сишных функций с параметрами.
Go to the top of the page
 
+Quote Post
XVR
сообщение Dec 2 2008, 18:37
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(QuickWitted @ Dec 2 2008, 17:50) *
вопрос
как обратиться к элементу массива?
как обратиться к элементу структуры из 6 байт?
как обратиться к переменной?
Массив, равно как и переменная, равно как и структура из 6ти байт - суть метки в сегменте данных (+ зарезервированное место, но это не существенно). Посмотри ассемблер после компилятора (ключ -s) и найди, как выглядят эти метки (скорее всего это будут имена переменных с подчеркиванием вначале). У себя в асм опиши их как .globl <name> и используй



упс, _Pasha опередил
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 00:06
Рейтинг@Mail.ru


Страница сгенерированна за 0.01534 секунд с 7
ELECTRONIX ©2004-2016