|
|
  |
Передача аргументов из Си в Асм и обратно, Кто как делает? |
|
|
|
Jun 13 2007, 09:05
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(AVL @ Jun 12 2007, 19:08)  Для каких именно? Я программирую сейчас для TMS320C55x. Передаю и получаю параметры через регистры и/или указатели на массивы. Для семейства TMS320F28xx. Я тоже передаю параметры в асм-подпрограмму через регистры AL, AH, а указатели через xar4, xar5, если их мало. И принимаю значение функции через асс. Сейчас пишу несколько заказных программ для КАНа, туда надо передавать один параметр, а получать четыре (один из них указатель). Мне удобно передавать по значению. Стал смотреть, что генерит компилятор. Оказалось, идёт некая возня со стеком. Присмотрелся - идёт передача по значению, отсюда и вопрос выплыл. Цитата(AVL @ Jun 12 2007, 19:08)  Есть полезный документ TMS320C55x Optimizing C/C++ Compiler User's Guide (spru281d.pdf). Документ посмотрю, спасибо, хотя проц немного другой. Цитата(Alex11 @ Jun 12 2007, 17:56)  Естественно, разнообразными способами. Как удобнее в звисимости от количества параметров, которое нужно передать. Если мало, то через регистры. Благо там все фиксировано. Интересует возврат в Си программу нескольких аргументов именно по значению. Можно ли сделать возврат разного числа аргументов?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 14 2007, 05:46
|
Частый гость
 
Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874

|
Цитата(=GM= @ Jun 13 2007, 13:05)  Интересует возврат в Си программу нескольких аргументов именно по значению. Можно ли сделать возврат разного числа аргументов? Врядли, ведь функция С может возвратить всего лишь одно значение.
|
|
|
|
|
Jun 14 2007, 06:10
|

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

|
Цитата(Warlord @ Jun 14 2007, 08:46)  Врядли, ведь функция С может возвратить всего лишь одно значение. Или возвращать указатель на структуру, или получать указатели на нужное количество переменых и устанавливать их значения. Цитата(=GM= @ Jun 12 2007, 21:29)  Стало интересно выяснить, а как вы делаете? Так, как нужно в конкретном случае.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 14 2007, 06:51
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(=GM= @ Jun 12 2007, 22:29)  Стало интересно выяснить, а как вы делаете? Беру и возвращаю структуру. т.е. Код typedef struct _ret_struct { ... ... ... } RET_STRUCT;
extern RET_STRUCT ext_func(...); Ну а делается это в 55хх согласно документации на его С-компилер: Код 5) The called function returns a value. It is placed in a register using the following convention: 16-bit integer value: AL 32-bit integer value: ACC 64-bit integer value: ACC/P 16- or 22-bit pointer: XAR4
[b]If the function returns a structure, the caller allocates space for the structure and passes the address of the return space to the called function in XAR4. To return a structure, the called function copies the structure to the memory block pointed by the extra argument. [/b]
In this way, the caller can be smart about telling the called function where to return the structure. For example, in the statement s= f(x), where S is a structure and F is a function that returns a structure, the caller can actually make the call as f(&s, x). The function f then copies the return structure directly into s, performing the assignment automatically.
If the caller does not use the return structure value, an address value of 0 can be passed as the first argument. This directs the called function not to copy the return structure. You must be careful to properly declare functions that return structures both at the point where they are called (so that the extra argument is passed) and at the point where they are declared (so the function knows to copy the result). Returning 64-bit floating-point values (long double) are returned similarly to structures. Т.е. Вам не надо задумываться о том, где эта структура лежит. Просто вернуть как будто по ссылке, а для С-компилера оно будет как будто по значению. И волки сыты, и овцы целы.
|
|
|
|
|
Jun 14 2007, 12:54
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(SM @ Jun 14 2007, 05:51)  Беру и возвращаю структуру.
Т.е. Вам не надо задумываться о том, где эта структура лежит. Просто вернуть как будто по ссылке, а для С-компилера оно будет как-будто по значению. И волки сыты, и овцы целы. Ну передача со структурой, также, как и с массивом, достаточно большой гемор, по-моему. В подпрограмме надо все адреса вычислять, получается много накладных расходов. Цитата(Warlord @ Jun 14 2007, 04:46)  Вряд ли, ведь функция С может возвратить всего лишь одно значение. Вот так я возвращаю ТРИ значения, см. фрагмент ниже Код ; To call from C-program: pending=checkCan(int errors, int status)
_checkCan:
movl xar5,#CANAES movl acc,xar5 mov *-sp[6],ah mov *-sp[7],al movl xar5,#CANARMP movl acc,*xar5 Два аргумента, errors и status, возвращаются через стек, флаг - через асс. Причём, можно использовать где угодно внутри программы. Одно пока непонятно, как автоматизировать вычисление положения аргументов в стеке, тогда можно было бы вызывать функции с разным числом аргументов.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 14 2007, 18:22
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(SM @ Jun 14 2007, 14:17)  Бред какой-то. Ни errors, ни status не могут возвращаться при таком объявлении. Они только передаются в функцию. Возвращаться может что-то переданное в ф-цию по указателю и что то ОДНО (пусть хоть байт, хоть структура), что является типом, возвращаемым функцией. И третьего не дано. Ну, я бы так с ходу не стал называть это бредом. Аргументы в функцию я не передаю, мне не надо, но, сишная программа, действительно, передаёт в программу через AL и AH. И одновременно, кладёт эти же значения в стек! Вопрос зачем? Дома у меня нет, завтра покажу дизассемблированный кусок, там прям видно, как сишная программа использует возвращенные значения, никаких фокусов, всё по-честному. Цитата(zltigo @ Jun 14 2007, 15:55)  А они и не возвращаются  они остаются лежать в мусоре стека, из этого мусора ASM программа их и извлекает - трюкачество на ровном месте, короче. В принципе для более-менее чистого С существует один более-менее легальный вариант - использовать разнобой между 'C' и Паскалевским соглашением по очистке стека от аргументов и вызывать реальную _cdecl функцию по _pascal прототипу. Это если конечно компилятор поддерживает. Да? А зачем тогда, по-вашему, их в стек класть вообще, в мусор? Просветите, не дайте помереть дурой(:-). У меня асм ничего не извлекает из стека, он туда кладёт, а вот сишная программа - берёт из стека и присваивает значения сишным переменным! Там кстати, не мусор, а хип, который организуется самим компилером.
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
Jun 14 2007, 19:04
|

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

|
Цитата(=GM= @ Jun 14 2007, 21:22)  Да? А зачем тогда, по-вашему, их в стек класть вообще, в мусор? Во время работы подпрограммы это не мусор. Мусором становится после выхода из подпрограммы, поскольку эта область стека освобождается и может быть затерта, например, обработчиком прерывания.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jun 14 2007, 19:57
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
GM, она их не кладет в стек, они живут там. Это собственно хранилище переменных вызывающей функции, и вызываемая не имеет никакого права там ковыряться. Конечно, это Ваше дело, сопли городить. Это мало того, что компиляторозависимо, еще и от оптимизации наверняка зависит, и, что хуже, если Вашу ф-цию кто-то вызовет из другой функции, в которой другой набор локальных переменных, или они в другом порядке описаны, то их смещения окажутся другими. А если не дай бог переменная, которую передавали, была static или глобальная... Вообще ужос! В общем - есть документированный способ передачи данных в ф-цию и из функции. Все остальное это хакерство, достойное школьника, только что узнавшего, как и что делают компиляторы. Более того, есть документы ANSI/ISO, а именно стандарт языка С, описывающие в одном из пунктов, что и как можно передавать в ф-цию, и что и как возвращать (естесвенно в пределах языка С). Советую обратиться к ним в первую очередь, после чего будет все однозначно ясно (hint - переменные, переданные в ф-цию по значению являются локальными для ф-ции, и она имеет право их изменять как ей угодно без малейшего влияния на то, откуда эти значения были переданы).
PS. То, что делаете Вы сравнимо со взломом программы - хакер точно зная где и что лежит, меняет даные на другие. Сменилась версия - и абзац.
P.P.S. Уж от кого, а от Вас я не ожидал таких вопросов.
|
|
|
|
|
Jun 15 2007, 16:16
|

Ambidexter
    
Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282

|
Цитата(SM @ Jun 14 2007, 18:57)  GM, она их не кладет в стек, они живут там. Это собственно хранилище переменных вызывающей функции, и вызываемая не имеет никакого права там ковыряться. Ну, ладно, осознал, что сделать-то можно, но будет чистое любительство и никакой преемственности. Цитата(SM @ Jun 14 2007, 18:57)  То, что делаете Вы сравнимо со взломом программы - хакер точно зная где и что лежит, меняет даные на другие. Сменилась версия - и абзац Ну вот, а я-то думал, что хакер - это почётное звание(:-) Цитата(SM @ Jun 14 2007, 18:57)  Уж от кого, а от Вас я не ожидал таких вопросов Come on, SM! Вопрос-то нормальный. Просто задрала эта си, век бы её не видать. У меня пространство двух переменных аппроксимируется полиномом 7 степени по одной координате и 5 - по другой, надо передать 12 параметров, да еще 4 длинных числа, формула на двух листах, да обратно надо передать температуру, давление и кой-какие служебные параметры... Вот я их и разделял на входной массив и на выходной, всего два регистра хар4 и 5, при входе копирую в область памяти входных параметров, при выходе - из другой. Ну, накладных расходов много, думал сократить. Вот ещё мысль мелькнула, передавать обратно через глобальные переменные. Что там стандарт говорит на этот счёт?
--------------------
Делай сразу хорошо, плохо само получится
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|