14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
|
||||||
1 | ||||||
Встроенный asm не понимает метки (GCC).28.05.2009, 20:39. Показов 11168. Ответов 64
Метки нет (Все метки)
Только не думайте, что я, как чуть что - сразу спрашивать бегу. Искал... (Вообще, вроде должен видеть все метки и к переменные, "как свои". Так я думал...) Добавлено через 9 часов 14 минут 6 секунд Пробовал в операнд (имя метки) добавлять "_" (одно нижнее подчёркивание) - нет...
0
|
28.05.2009, 20:39 | |
Ответы с готовыми решениями:
64
Встроенный asm и 64-битные регистры Встроенный asm не видит метку (Borland 3.1) AVRstudio 4 + GCC + ASM Нужно вставить блок на асме, но он не понимает asm и __asm |
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
|
|
02.06.2009, 11:03 [ТС] | 41 |
"Что позволено Гераклу, Не позволено в gcc" Вот, читал тут.http://www.ibiblio.org/gferg/l... HOWTO.html Там о переходах из блока asm вообще скромно умалчивают.
0
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
02.06.2009, 11:11 | 42 |
Ultrator, не понял чего? Переход из ассемблерного кода на внешнюю метку после return вполне возможен. В крайнем случае, это можно сделать без метки, каким-либо другим способом. Например, используя eip или еще что-то. Сейчас просто времени нет смотреть что-то по этому вопросу, других дел хватает.
Добавлено через 3 минуты 2 секунды Но любой такой способ, как было упомянуто выше Evg, будет являться хаком. Скорее всего.
0
|
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
|
|
02.06.2009, 11:17 [ТС] | 43 |
А в таком асмовом коде, как вариант 3, будет окончание типа:
...................jc OUT1; ....................... jmp OUT2; //а как же иначе? OUT1: mov $0, %0; //запись "0" в "res", после jc OUT2: //конец блока. return res; } Что мы имеем? Один "лишний" jmp... Добавлено через 2 минуты 17 секунд А в GCC - покажи, плз, как, если знаешь... (Уже 2 дня пытаюсь это сделать)
0
|
02.06.2009, 11:43 | 44 | ||||||||||
Блин, да нарисуйте же вы мне код на ассемблере для умножения в цикле - всё сделаю. Для таких конструкций, чтобы избежать лишнего jmp'а в наиболее часто работающей ветке, используется subsection
> В других компилерах - конечно! Другие компиляторы работают с вставками предельно тупо. Ассемблерная вставка это полюс, через который не работает ни одна оптимизация. Только за счёт такого поведения возможно из вставки непосредственно обращаться к переменным, меткам и т.п. Добавлено через 1 минуту 22 секунды Реально получается, что туеву кучу времени и слов потратил только потому, что не понимаю интеловский ассемблер, а те кто знает начисто игнориуют несколько раз написанную просьбу написать код Добавлено через 8 минут 41 секунду Если настолько лениво писать код, то посмотрите, как выглядит реализация spinlock'а:
Т.е. если написать код (в предположении, что процедура проинлайнится),
Код
код, соотвествующий trampampam1 1: lock; decl %0 js 2f код, соотвествующий trampampam1 .... <где-то в хвосте кодовской секции> 2: cmpl $0,%0 rep; nop jle 2b jmp 1b
0
|
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
|
|
02.06.2009, 12:16 [ТС] | 45 |
MULL источник
Выполняет беззнаковое умножение источника (регистр или переменная) на содержимое EAX и помещает результат в EDX:EAX. Если старшее слово в результате (EDX) не равно 0, флаг CF (и флаг OF тоже) - "1", иначе - "0".
0
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|||||||||||
02.06.2009, 12:16 | 46 | ||||||||||
Мдя...еще спины припахал.
Я сделал проще:
0
|
02.06.2009, 12:26 | 47 |
Потому что если не хотите выдать код, чтобы я сделал правильно - дал хоть образец того, как это нужно делать.
Добавил опцию -O1, после мусорный код с чистой совестью снесло и метку заодно. Попытки обмануть оптимизатор в большинстве случаев означают, что ты его обманешь для данной версии компилятора и при данном наборе опций. Шаг влево или шаг вправо - работать перестаёт. Ну либо если пытаешься обмануть, надо как минимум понимать, как работает компилятор и оптимизации
1
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
||||||
02.06.2009, 12:47 | 48 | |||||
Блин, не на ту кнопку попал
С кодом вообще не ко мне. Выше я написал код, который будет работать. Если ты не можешь справиться с опциями оптимизации это твоя личная проблема и недостаток знаний. Я выше поэтому и написал, что способов дофига. Добавлено через 15 минут 54 секунды Evg, да, тьфу...
Ладно, я привел уже два рабочих примера. Сами разбирайтесь со спинами там, где и без легко можно обойтись.
0
|
02.06.2009, 13:04 | 49 | |||||
См. комментарии около ассемблерных конструкций и поправьте код, если написал неправильно:
Код
$ gcc t.c -O2 -fomit-frame-pointer -c $ objdump -d t.o 00000000 <iFactorial>: 0: b8 01 00 00 00 mov $0x1,%eax 5: 85 c9 test %ecx,%ecx 7: 74 08 je 11 <iFactorial+0x11> 9: 0f af c1 imul %ecx,%eax c: 72 04 jb 12 <iFactorial+0x12> e: 49 dec %ecx f: 75 f8 jne 9 <iFactorial+0x9> 11: c3 ret 12: b8 00 00 00 00 mov $0x0,%eax 17: 72 f8 jb 11 <iFactorial+0x11> Добавлено через 5 минут 13 секунд Ога, вылизываем процедуру из 10 тактов и для обмана компилятора дёргаем процедуру, которая исполняется несколько сотен или тысяч тактов Добавлено через 2 минуты 42 секунды Я тебе уже написал, что с опциями оптимизации код не будет работать. Если ты уже забыл, то постановка задачи не в том, чтобы написать код, который хоть как-то работал, а код с предельной производительностью Тем не менее пока ещё не привёл ни одного рабочего кода. Код, который не работает в режиме с оптимизациями, рбочим не считается
0
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
02.06.2009, 13:43 | 52 |
Все канает. Достаточно вставить любой код, который компилер не сможет обработать на стадии компиляции и он попадет в бинарь. Я дал рабочую идею. Пример рабочий привел. Башка есть? Значит, доделаешь.
0
|
02.06.2009, 13:48 | 53 |
Тогда приведи код для поставленной задачи, потому как начинается детский сад и словесная перепалка: "канает" - "не канает"
Постановка была такая: Функция должна считать факториал и при переполнении возвращать 0. Хотелось сделать максимально быструю, насколько возможно
0
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
02.06.2009, 14:05 | 54 |
Детский сад, я тебе выше привел код, который будет работать.
Если решать вопрос о нахождении факториала, то я бы вообще так не извращался в метками, прыжками из ассемблерных вставок, и возни с оптимизацией. Если решать только посталенную задачу, то все элементарно, безо всяких извращений с прыжками, которыми заразили с самого начала. Добавлено через 1 минуту 26 секунд Тогда самый обычный чистый ассемблерный код все решает. Добавлено через 5 минут 41 секунду Короче, если брать решение именно задачи с факториалом, то все вещи здесь описанные нами на фиг не нужны.
0
|
02.06.2009, 14:16 | 55 |
Ещё раз говорю. Постановка задачине в том, чтобы написать работающий код, а в том, чтобы сделать код максимально быстрым
Тут не просто факториал, а с переполнением. Чисто теоретически переполнение вроде бы как ловится по факту того, что после умножения число стало меньше, но из-за слабости с математикой на 100% я в этом не уверен. Как ещё по другому отловить переполнение я не знаю. Да и опять-таки вопрос не в "простонахождении факториала", а в предельной скорости кода (собственно из-за чего Ultrator и завёл эту тему) Прыжки вылезли из-за того, что нужно отловить факт преполнения А я к этому уже давно веду. Но чистый ассемблер я бы писать не стал по нескольким причинам: 1. В этом месте надо понимать программные соглашения (хотя я косвенно это зацепил, принудительно распределив res на регистр %eax) 2. Код на ассемблере уже нельзя будет inline'ить. Код написанный в виде процедуры обкладки плюс ассемблерная вставка - можно. Вообще высокопроизводительные библиотеки на этом базируются - строятся такие примитивные кирпичики в виде коротких процедур, далее строится нужное тебе большое выражение, состоящее из этих кирпичиков, а далее компилятор всё это дело по возможности оптимальным образом схлопывает. Единственно, что gcc далеко не всегда сделает это максимально оптимальным образом (мы с тобой уже это обсуждали), а потому без доработки напильником иногда не обойтись. При этом всегда нужно чётко осознавать, что код должен быть корректным. И по возможности избегать читов, которые я приводил с asm entry Я на 99% уверен, что Ultrator'у нахер не сдался этот факториал. Ему нужно понять, как реализовывать подобные вещи
0
|
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
|
|
02.06.2009, 14:37 | 58 |
Добавлено через 1 минуту 59 секунд Ладно, код на асме ты ему вроде написал. Способ оставить метку у него теперь тоже есть. Все зашибись
0
|
02.06.2009, 14:41 | 59 |
Если бы я не разбирался в том, как работают компиляторы - я бы смог изобрести только дополнительный вариант с двумя goto. А здесь фактически появился лишь один дополнительный переход
Кстати. в моём коде на ассемблере в самом конце можно сделать "ret" вместо перехода на метку "2", но это менее честный вариант, т.к. он коряво отработает в том случае, если процедура про'inline'иться (ну и не говоря уж о том, что это гораздо более явное использование знаний о программных соглашениях, а потому способ менее честный)
0
|
14 / 10 / 1
Регистрация: 28.04.2009
Сообщений: 219
|
|
02.06.2009, 14:52 [ТС] | 60 |
Наконец, понял я, в чём проблема.
В том, что он её инлайнит. Только и всего. Если ф-ю не вызывать нигде - всё пучком, хоть с оптимизацией, хоть без. Вот попробуйте...
0
|
02.06.2009, 14:52 | |
02.06.2009, 14:52 | |
Помогаю со студенческими работами здесь
60
Asm вставки в AVR GCC STM32 + ASM + arm-none-eagi-gcc = непонятки Использование внешних переменных в asm вставке и компиляцией gcc Реализовать 2 функции с использованием языка C и конструкции asm компилятора gcc Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |