попробовал три, всё равно через регистры. Да уже и не важно, твое утверждение, что при каком-то флаге оптимизации, кровь из носу компилятор кладет в стек не подтвердилось.
push {r4, r5, r7}
sub sp, sp, #20
add r7, sp, #0
str r2, [r7, #8]
str r3, [r7, #4]
mov r3, r0
Мы о разных вещах говорим.
Мне надо до “большого” компуктера дойти, там софт стоит.
Я не отличаюсь голословностью и раздэзы на асме я видел миллионами, поверь.
Вот как выглядит фрейм на STM32 и он СТАНДАРТЕН(!)
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
_Z7_squarehtjilPx:
push r8
push r9
push r10
push r11
push r12
push r13
push r14
push r15
push r16
push r17
push r28
push r29
in r28,__SP_L__
in r29,__SP_H__
sbiw r28,21
in __tmp_reg__,__SREG__
cli
out __SP_H__,r29
out __SREG__,__tmp_reg__
out __SP_L__,r28
.L__stack_usage = 33
std Y+1,r24
std Y+3,r23
std Y+2,r22
std Y+5,r21
std Y+4,r20
std Y+7,r19
std Y+6,r18
std Y+8,r14
std Y+9,r15
std Y+10,r16
std Y+11,r17
std Y+13,r13
std Y+12,r12
На AVR - это совсем “не_тот_кампот” )))
Давай на каких-нибудь общих функциях потренируемся.
Чтобы результат было видно и мне и тебе…
И раздэз откуда? Протеус компилил или как?
R0 - R15 помоему “урезанные” регистры и они не все операции поддерживают (вроде бы как)
Некоторые компиляторы “хранят” волшебные $00 и $ff в регистрах и не трогают их вообще.
Это дюже сильно зависит от компилятора, опции оптимизации работают не так сильно, как разница в компиляторе.
Напиши пару - тройку простых функций и я скомпилирую их для разных платформ и посмотрим разницу.
Возьми разные переменные, 8, 16 и 32 бита (float не бери, там сложно) и в функции сделай с ними арифметику простую. Ну и return по классике…
Посмотрим вместе, раз уж взялись на для посмотреть… )
Другими словами, ты хочешь чтобы я заебал компилятор, чтобы он всё таки положил переменную в стек? Делать ото мне нехер. И лосю понятно, что рано или поздно он так и сделает.
Давай я сам тогда напишу и откомпилирую.
Я одного не пойму, зачем ты тогда начал спор со мной?
я ж вроде ответил. ты утверждал, что локальные переменные “по любому” будут в стеке, я сказал “не обязательно будут в стеке” и от флагов оптимизатора не зависит. понятно, что если регистры заняты, он будет класть в стек, куда ж еще, но если есть свободные, то заставить его положить переменную в стек можно, ну разве что асм вставками, и то, с учетом указателя на стек, если положил пять переменных, то и забрать надо пять переменных, иначе адрес возврата хрен прочтешь, у него lifo организация и начинается с хвоста памяти, что у avr, что у stm. Одинаково.
Нет, стэк здесь не участвует вообще!
in r28,__SP_L__
in r29,__SP_H__
sbiw r28,21
Вычитаем длину фрейма а стэк мы не трогаем…
И доступ к переменной индекс + смещение
std Y+5,r21
-О0 = сохраняет переменные на фрейме
-О1 = сохраняет некоторые регистры проца
-О2 = скорее всего и регистры проца не будет сохранять.
Дривер, ну уж попробуй уже ВСЕ опции, это же не трудно)))
Здесь не совсем видно саму оптимизацию, ибо параметров мало. Всегда переменная пробрасывается и возвращается в R0 если явно не указать другое.
Надо больше параметров и разных пробрасывать - разница будет увнее.
А с указателями там еще интереснее…
да сколько бы то ни было, видно на обеих скринах mov r1, r0 и ни одного POP
Здаецца мне, что вы понятия не имеете о работе фреймов.
И зачем там POP нужен?
Действительно, зачем?
Мы выделяем “кусочек” стэка и занимаем его локальными переменными, которые не БОЛТАЮТСЯ на стэке, он вообще не участвует(!!!)
Мы берем ИНДЕКС и отнимаем от него нужный кусок памяти и стэк работает так - же(!!!) Прикинь, если на входе в функцию нежданно прилетит прерывание и что? Сливать тосол? → ? Нет, конечно, стэк будет работать и сохранит контент, а через индексную адресацию мы можем обращаться к ЛЮБОЙ переменной БЕЗ команд PUSH и POP. (!!!)
вы правы, я понятия не имею что такое “фрейм” относительно архитектуры мк.
На мой взгляд - Вам бы обоим посмотреть исходный код FORTH. А то у понимания между Вами нет. Для обоих полезно изучить.
О! Точняк, пришел спец по мак адресам и всё разрулил. Казалось бы, кого еще здесь не хватает.
Я это сразу понял.
Фрейм (frame - рамка) это такая штука, которая была еще на Z80 процах, IX и IY были так называемые индексные регистры. На современных камнях они есть однозначно. Так вот, все “вкусное” в том, что ты можешь выделить небольшой кусочек памяти и обращаться к любому элементу. Ну что-то типа массива, только на аппаратном уровне проца.
Вот и весь “Х” до копейки… )
Чиркани, я попробую скомпилировать. Но не 8086 асм, я его ненавижу)))



