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

 
 
 
Reply to this topicStart new topic
> Передача аргументов из Си в Асм и обратно, Кто как делает?
=GM=
сообщение Jun 12 2007, 18:29
Сообщение #1


Ambidexter
*****

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



Народ, у меня такой вопрос назрел.

Для тексасовских процов, кто как передаёт аргументы из головной программы, написанной на Си в ассемблерную подпрограмму и как получает обратно?

До недавнего времени передавал обычно адреса двух массивов, один для входных аргументов, второй для выходных. Ещё раньше передавал значения через стек. Теперь стал задумываться о передаче и получении аргументов по значению.

Стало интересно выяснить, а как вы делаете?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Alex11
сообщение Jun 12 2007, 18:56
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 106
Регистрация: 23-10-04
Из: С-Петербург
Пользователь №: 965



Естественно, разнообразными способами. Как удобнее в звисимости от количества параметров, которое нужно передать. Если мало, то через регистры. Благо там все фиксировано.
Go to the top of the page
 
+Quote Post
AVL
сообщение Jun 12 2007, 20:08
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 392
Регистрация: 29-05-07
Из: Москва
Пользователь №: 28 020



Для каких именно?
Я программирую сейчас для TMS320C55x. Передаю и получаю параметры через регистры и/или указатели на массивы.
Есть полезный документ TMS320C55x Optimizing C/C++ Compiler User's Guide (spru281d.pdf).
В разделе Run-Time Environment->Function Structure and Calling Conventions описано какие регистры для чего используются при вызове дочерней подпрограммы из родительской.
Например регистры xar0...xar4 для передачи указателей, t0, t1, ar0...ar4, ac0...ac2 - аргументы по значению. Возврат значения в t0, ac0.
Более подробно и обо всех возможностях см. указанный документ.

Сообщение отредактировал AVL - Jun 12 2007, 20:08
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 13 2007, 09:05
Сообщение #4


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) *
Естественно, разнообразными способами. Как удобнее в звисимости от количества параметров, которое нужно передать. Если мало, то через регистры. Благо там все фиксировано.

Интересует возврат в Си программу нескольких аргументов именно по значению. Можно ли сделать возврат разного числа аргументов?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Warlord
сообщение Jun 14 2007, 05:46
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 121
Регистрация: 23-09-05
Из: Москва
Пользователь №: 8 874



Цитата(=GM= @ Jun 13 2007, 13:05) *
Интересует возврат в Си программу нескольких аргументов именно по значению. Можно ли сделать возврат разного числа аргументов?

Врядли, ведь функция С может возвратить всего лишь одно значение.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2007, 06:10
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
SM
сообщение Jun 14 2007, 06:51
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 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.


Т.е. Вам не надо задумываться о том, где эта структура лежит. Просто вернуть как будто по ссылке, а для С-компилера оно будет как будто по значению. И волки сыты, и овцы целы.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 14 2007, 12:54
Сообщение #8


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, возвращаются через стек, флаг - через асс. Причём, можно использовать где угодно внутри программы.

Одно пока непонятно, как автоматизировать вычисление положения аргументов в стеке, тогда можно было бы вызывать функции с разным числом аргументов.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SM
сообщение Jun 14 2007, 14:17
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Бред какой-то. Ни errors, ни status не могут возвращаться при таком объявлении. Они только передаются в функцию. Возвращаться может что-то переданное в ф-цию по указателю и что то ОДНО (пусть хоть байт, хоть структура), что является типом, возвращаемым функцией. И третьего не дано.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2007, 15:55
Сообщение #10


Гуру
******

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



Цитата(SM @ Jun 14 2007, 17:17) *
Ни errors, ни status не могут возвращаться при таком объявлении.

А они и не возвращаются smile.gif они остаются лежать в мусоре стека, из этого мусора ASM программа их и извлекает - трюкачество на ровном месте, короче. В принципе для более-менее чистого С существует один более-менее легальный вариант - использовать разнобой между 'C' и Паскалевским соглашением по очистке стека от аргументов и вызывать реальную _cdecl функцию по _pascal прототипу. Это если конечно компилятор поддерживает.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 14 2007, 18:22
Сообщение #11


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) *
А они и не возвращаются smile.gif они остаются лежать в мусоре стека, из этого мусора ASM программа их и извлекает - трюкачество на ровном месте, короче. В принципе для более-менее чистого С существует один более-менее легальный вариант - использовать разнобой между 'C' и Паскалевским соглашением по очистке стека от аргументов и вызывать реальную _cdecl функцию по _pascal прототипу. Это если конечно компилятор поддерживает.

Да? А зачем тогда, по-вашему, их в стек класть вообще, в мусор? Просветите, не дайте помереть дурой(:-). У меня асм ничего не извлекает из стека, он туда кладёт, а вот сишная программа - берёт из стека и присваивает значения сишным переменным! Там кстати, не мусор, а хип, который организуется самим компилером.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 14 2007, 19:04
Сообщение #12


Гуру
******

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



Цитата(=GM= @ Jun 14 2007, 21:22) *
Да? А зачем тогда, по-вашему, их в стек класть вообще, в мусор?

Во время работы подпрограммы это не мусор. Мусором становится после выхода из подпрограммы, поскольку эта область стека освобождается и может быть затерта, например, обработчиком прерывания.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
SM
сообщение Jun 14 2007, 19:57
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



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

PS.
То, что делаете Вы сравнимо со взломом программы - хакер точно зная где и что лежит, меняет даные на другие. Сменилась версия - и абзац.

P.P.S.
Уж от кого, а от Вас я не ожидал таких вопросов.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Jun 15 2007, 16:16
Сообщение #14


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, при входе копирую в область памяти входных параметров, при выходе - из другой. Ну, накладных расходов много, думал сократить.

Вот ещё мысль мелькнула, передавать обратно через глобальные переменные. Что там стандарт говорит на этот счёт?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
SM
сообщение Jun 18 2007, 10:14
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881



Цитата(=GM= @ Jun 15 2007, 20:16) *
Вот ещё мысль мелькнула, передавать обратно через глобальные переменные. Что там стандарт говорит на этот счёт?


Нормально все говорит про глобальные. Но я бы просто передал адын указатель на структуру, где все лежит. И входные, и выходные.
Go to the top of the page
 
+Quote Post

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

 


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


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