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

 
 
4 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> Ламерской вопрос, массив unsigned char
Fortune
сообщение Feb 8 2007, 11:10
Сообщение #1


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

Группа: Свой
Сообщений: 75
Регистрация: 1-02-07
Из: Украина
Пользователь №: 24 940



Я с ARM еще не работал, но у меня появились вопросы.
Если обьявить массив типа unsigned char в ОЗУ
сколько будет занимать один элемент в памяти?
Можно ли сделать так, чтобы он занимал 1 байт?
Если нет, то как легче всего это сделать программно.
Go to the top of the page
 
+Quote Post
SergeyDDD
сообщение Feb 8 2007, 11:22
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 231
Регистрация: 7-12-06
Из: Киев
Пользователь №: 23 248



все зависит от контроллера памяти и самой памяти где будет массив

Сообщение отредактировал SergeyDDD - Feb 8 2007, 11:24
Go to the top of the page
 
+Quote Post
Fortune
сообщение Feb 8 2007, 11:26
Сообщение #3


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

Группа: Свой
Сообщений: 75
Регистрация: 1-02-07
Из: Украина
Пользователь №: 24 940



Цитата(SergeyDDD @ Feb 8 2007, 12:22) *
все зависит от контроллера памяти и самой памяти где будет массив


Ну например для AT91SAM7S64, если разместить во внутреннем ОЗУ?
Go to the top of the page
 
+Quote Post
etoja
сообщение Feb 8 2007, 11:34
Сообщение #4


Профессионал
*****

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



При компиляции программы можно указать ключи для выравнивания переменных на границу одного, двух или четырёх байт. Например, при использовании компилятора ICCV7 (Imagecraft) для процессоров ADuC702x и LPC21xx байтовые переменные занимают в памяти 1 байт.
Go to the top of the page
 
+Quote Post
SergeyDDD
сообщение Feb 8 2007, 11:57
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 231
Регистрация: 7-12-06
Из: Киев
Пользователь №: 23 248



Цитата(Fortune @ Feb 8 2007, 12:26) *
Цитата(SergeyDDD @ Feb 8 2007, 12:22) *

все зависит от контроллера памяти и самой памяти где будет массив


Ну например для AT91SAM7S64, если разместить во внутреннем ОЗУ?


Как правило внутреннее ОЗУ поддерживают операции с байтами
А вообще это справочная информация. См. документацию.

А еще проще сходу попробовать на железе
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 12:00
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



по-моему ерунду говорите. Массив всегда будет расположен ЛИНЕЙНО. Точка. И один char в массиве всегда занимает один байт
PS "по-моему" добавлено только для смягчения фразы, но никак не по причине наличия сомнений ;-)
Go to the top of the page
 
+Quote Post
SergeyDDD
сообщение Feb 8 2007, 12:15
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 231
Регистрация: 7-12-06
Из: Киев
Пользователь №: 23 248



Цитата(DASM @ Feb 8 2007, 13:00) *
по-моему ерунду говорите. Массив всегда будет расположен ЛИНЕЙНО. Точка. И один char в массиве всегда занимает один байт
PS "по-моему" добавлено только для смягчения фразы, но никак не по причине наличия сомнений ;-)


Почему же ерунду? Проблема может возникнуть с железом, а не с компилятором.
Для примера возьмем EP7312:
ширина шины данных управляется линиями HALFWORD и WORD (думаю назначение понятно).
Для 32 разрядной шины используются линии адреса начиная с A2.
Так вот в такой конфигурации записать байт можно только по адресам 0, 4, 8, 12, 16...

А вот с SDRAM памятью и внутренней (в EP7312) такой проблемы нет.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 12:37
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Значит компилер будет считывать 32-битное значения и выдирать сам байиы, если я правильно Вас понял. Массив в любом случае по адресам будет лежать слитно, иначе вся арифметика указателей летит к чертовой матери вместе с Керниганом и этим.. как его.. Ритчи
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Feb 8 2007, 13:19
Сообщение #9


Дух погибшего транзистора
****

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



Цитата(DASM @ Feb 8 2007, 12:37) *
Значит компилер будет считывать 32-битное значения и выдирать сам байиы,

Тут уж, наверно, не компилер, а сам процессор.


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 13:23
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



не важно кто, важно что для программисты массив линеен без разрывов, и заботиться не надо. Заботиться надо в union когда char или short в него входит и , одновременно, рассматривается как массиы. Тогда pragma pack(1) конечно
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 8 2007, 13:38
Сообщение #11


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Сколько текста!
Сколько времени потрачено!
Неужто в облом написать пример в четыре строки, собрать и посмотреть листинг?
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 8 2007, 14:56
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(SpiritDance @ Feb 8 2007, 13:19) *
Цитата(DASM @ Feb 8 2007, 12:37) *

Значит компилер будет считывать 32-битное значения и выдирать сам байиы,

Тут уж, наверно, не компилер, а сам процессор.

Вы оба неправы, господа. Этим занимается аппаратно контроллер памяти (неважно какой, SDRAM, SRAM, DDR) - все эти дела совершенно прозрачны для программиста и для процессора, исполняющего команды программиста. smile.gif
Обратите внимание - несмотря на то, что разрядность шины данных процессора увеличивается (от 8 битных 8088, далее через 16 битные 8086/80286, через 32 битные 80386/Pentium-ы, а теперь есть и 64 битные ...) - ПО КАЖДОМУ АДРЕСУ ПАМЯТИ ЛЕЖИТ РОВНО ОДИН БАЙТ !!!
С точки зрения любого процессора (и программиста) физическая память является линейной структурой байтов, адрес каждого байта уникален и отличается от адреса предыдущего и последующего ровно на единицу.
32 разрядный процессор "хочет" загрузить себе в регистр один байт из адреса 0x123456FF, и его совершенно не волнует, каким образом внешняя память "исполнит его желание". Более того, проц не обязан "знать", что за память расположена по этому адресу. Дальнейшие действия целиком и полностью возложены на контроллер памяти, который всё это "знает". Если память 32 разрядная - будет выполнено ДВА цикла чтения - один по адресу 0x123456FC, другой по адресу 0x12345700, а оставшиеся два младших бита в исходном адресе будут определять, как расположить считанные 8 байт на 32 разрядной шине так, чтобы процесоор "почувствовал", будто он и вправду считал двойное слово с адреса 0x123456FF.
ДВА цикла чтения заменятся на ОДИН цикл в одном случае - если адрес кратен 4. Поэтому у программиста (который, в отличие от процессора, знает свою архитектуру аппаратной части) есть выбор - указать компилятору, как предпочтительнее располагать данные в памяти (align). Хочется сэкономить память - указывай align=1, но тогда при доступе к 3 элементам из 4 будешь "попадать" по времени на ДВА цикла чтения; если памяти море - указывай align=4 (вроде как это по умолчанию), тогда каждый объект массива char будет лежать "как король" в адресах, кратных 4, чтобы не тратить лишнее время на доступ к нему.
Если контроллер памяти очень "умный" - он может сильно ускорять процесс считывания, например, вести кэш, и недавно считанное значение не считывать заново, или при доступе по определённым адресам на чтение/запись генерировать исключения и т. п. Часть этих функций современные процессоры типа Pentium взяли себе на борт (кэш первого уровня, защита памяти и генерация исключений и т п), часть оставили снаружи (кэш второго уровня, разделение RAM/ROM).


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 15:02
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



ну я собсно и сказал - по барабану кто будет делать, главное что программисту пофик. Зачем забивать себе голову лишними знаниями?
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 8 2007, 15:34
Сообщение #14


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(DASM @ Feb 8 2007, 15:02) *
ну я собсно и сказал - по барабану кто будет делать, главное что программисту пофик. Зачем забивать себе голову лишними знаниями?

А вот это кто сказал ?
Цитата(DASM @ Feb 8 2007, 12:37) *
Массив в любом случае по адресам будет лежать слитно, иначе вся арифметика указателей летит к чертовой матери вместе с Керниганом и этим.. как его.. Ритчи

Массив char в физической памяти будет лежать так, как на это указывает #pragma pack, то бишь выравнивание, если 4, то каждый элемент массива будет расположен с адреса, кратного 4, то есть занимать 4 байта.
И Керниган с Ритчи тут ни при чем. И арифметика указателей в порядке. Если Вы прибавите к указателю единицу, прибавка к адресу в машинном коде составит много больше - это зависит от размера элемента, на который указывает этот указатель и от выравнивания. Это уже работа компилятора.
А вот преобразование некратных адресов в адреса памяти (то, о чем я писал в пред. посте) - это работа контроллера памяти.
Это разные и совершенно не связанные вещи.


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Feb 8 2007, 15:49
Сообщение #15


Дух погибшего транзистора
****

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



Ну я то под процессором имел ввиду сам мк, а не собсвенно алу, но за ликбез спасибо. ж)


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 15:51
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



"Массив char в физической памяти будет лежать так, как на это указывает #pragma pack, то бишь выравнивание, если 4, то каждый элемент массива будет расположен с адреса, кратного 4, то есть занимать 4 байта."
Давайте оставим впокое физическую память, будем говорить про память, адресуемую по скажем [R0] и пусть сама эта память лежит где хочет.
Так вот я утверждаю, что при инкременте R0 на единицу мы получаем доступ к следущему элементу массива. И никакие прагмы паки тут совершенно роли не играют. Не так ?
pragma pack является директивой выравнивания структур, она не имеет отношения к массивам. По крайней мере в части их размещения
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 8 2007, 16:30
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(DASM @ Feb 8 2007, 15:51) *
"Массив char в физической памяти будет лежать так, как на это указывает #pragma pack, то бишь выравнивание, если 4, то каждый элемент массива будет расположен с адреса, кратного 4, то есть занимать 4 байта."
Давайте оставим впокое физическую память, будем говорить про память, адресуемую по скажем [R0] и пусть сама эта память лежит где хочет.
Так вот я утверждаю, что при инкременте R0 на единицу мы получаем доступ к следущему элементу массива. И никакие прагмы паки тут совершенно роли не играют. Не так ?
pragma pack является директивой выравнивания структур, она не имеет отношения к массивам. По крайней мере в части их размещения

Зависит от компилятора, размера элемента массива и установленного выравнивания !!!
Если мы говорим о массиве char, размер элемента равен 1.
Если мы установили выравнивание данных, равное 16, то, чтобы получить доступ к следующему элементу массива типа char, Вам в приведенном Вами примере придется увеличить R0 на 16.
В части различия компиляторов -- часть компиляторов применяет #pragma pack только к структурам, при этом для остальных типов у них есть что-то типа #pragma data_align. Это непринципиально. И обсуждалось уже здесь


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 16:39
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



И что ? Вы хотите сказать, что вашим шаманством я могу сделать такое -
char data[256];
printf ("%d\r\n" (int) &data[1] - (int) &data[0]);
и получить на экране 16 ? Сообщите пожалуйста такой удивительный компилятор и я посыплю голову пеплом
RVDS на этот счет говорит ясно
"There are no packed array types. A packed array is an array of objects of
packed type. There is no padding in the array."
Go to the top of the page
 
+Quote Post
Alex03
сообщение Feb 8 2007, 17:02
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(Demeny @ Feb 8 2007, 16:56) *
Вы оба неправы, господа. Этим занимается аппаратно контроллер памяти (неважно какой, SDRAM, SRAM, DDR) - все эти дела совершенно прозрачны для программиста и для процессора, исполняющего команды программиста. smile.gif

ИМХО тут неправы Вы. Для программиста не так уж и всё прозрачно, если конечно он не на бейсике пишет.
Цитата
Обратите внимание - несмотря на то, что разрядность шины данных процессора увеличивается (от 8 битных 8088, далее через 16 битные 8086/80286, через 32 битные 80386/Pentium-ы, а теперь есть и 64 битные ...) - ПО КАЖДОМУ АДРЕСУ ПАМЯТИ ЛЕЖИТ РОВНО ОДИН БАЙТ !!!

На некотором подмножестве из всех имеющихся платформ.
Цитата
С точки зрения любого процессора (и программиста) физическая память является линейной структурой байтов, адрес каждого байта уникален и отличается от адреса предыдущего и последующего ровно на единицу.

Не всегда и не везде.
Цитата
32 разрядный процессор "хочет" загрузить себе в регистр один байт из адреса 0x123456FF, и его совершенно не волнует, каким образом внешняя память "исполнит его желание". Более того, проц не обязан "знать", что за память расположена по этому адресу. Дальнейшие действия целиком и полностью возложены на контроллер памяти, который всё это "знает". Если память 32 разрядная - будет выполнено ДВА цикла чтения - один по адресу 0x123456FC, другой по адресу 0x12345700, а оставшиеся два младших бита в исходном адресе будут определять, как расположить считанные 8 байт на 32 разрядной шине так, чтобы процесоор "почувствовал", будто он и вправду считал двойное слово с адреса 0x123456FF.

На x86 оно реализовано ради совместимости, на очень многих других платформах этого нет. А есть или исключения, или игнорирование младших битов (как в случае с ARM)
К томуже в тех же x86-расширениях (типа MMX/SSE/SSEx) есть команды допускающие только обращение к выравненным данным.
Цитата
Хочется сэкономить память - указывай align=1, но тогда при доступе к 3 элементам из 4 будешь "попадать" по времени на ДВА цикла чтения; если памяти море - указывай align=4 (вроде как это по умолчанию), тогда каждый объект массива char будет лежать "как король" в адресах, кратных 4, чтобы не тратить лишнее время на доступ к нему.

Применительно к char (на х86) чтение будет всегда одно.

PS а архитектуры всякие бывают, не надо всех под гребёнку x86 причёсывать.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 17:05
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



SSE4 это хорошо... а что с моим вопросом ?
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 8 2007, 17:09
Сообщение #21


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(DASM @ Feb 8 2007, 16:39) *
И что ? Вы хотите сказать, что вашим шаманством я могу сделать такое -
char data[256];
printf ("%d\r\n" (int) &data[1] - (int) &data[0]);
и получить на экране 16 ? Сообщите пожалуйста такой удивительный компилятор и я посыплю голову пеплом
RVDS на этот счет говорит ясно
"There are no packed array types. A packed array is an array of objects of
packed type. There is no padding in the array."

Ага, я понял. Мы говорим о разных вещах. Вы в приведенном примере путаете УКАЗАТЕЛЬ на элемент и АДРЕС элемента в памяти. Это разные вещи.
Операция & возвращает указатель на элемент, и результат будет равен 1. По сути, указатель - это всего лишь ИНДЕКС элемента в сегменте данных программы. Именно поэтому указатель всегда указывает на вполне ОПРЕДЕЛЁННЫЙ тип данных, чтобы компилятор мог правильным образом обслуживать арифметику указателей. Например,
Код
double * pDouble;
double data[100];
pDouble = &(data[45]);
pDouble = pDouble + 1;

Вас же не удивляет такая операция - указатель увеличился на 1, а указывает уже на 46 элемент массива double (что говорит о том, что адрес сместился на 8). Если Вы отпечатаете pDouble, то увидите, что он действительно увеличился всего на 1.
А изначально Ваш пример содержал регистр процессора R0, на уровне машинных кодов регистр косвенной адресации действительно увеличится на число, зависящее от размера элемента и от выравнивания данных.
Чтобы не продолжать спор, я готов его завершить, если Вы мне скажете, как я могу разместить массив char data[200000] с адресов, кратных 4, чтобы не делать лишнюю работу контроллеру 32 разрядной памяти при доступе к каждому элементу? Если, по Вашему, невозможно применить выравнивание к массивам ...


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 17:12
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



мы по прежнему друг друга не понимаем. Не можете. Можно указать что начальный адрес массивы будет с адреса кратного 4, но все char - ы в нем будут идти ПОСЛЕДОВАТЕЛЬНО и адрес последнего элемента будет N + (200000-1)
Перефразирую так. Имеем линейную память. 0,1,2,3,4,5,6,7....
Вы можете вашими директивами расположить массив чаров так, что [0] лежал в 0-й ячейке, а [1] в 4-ой ячейке ? Я утверждаю что нет
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 8 2007, 17:23
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(DASM @ Feb 8 2007, 17:12) *
мы по прежнему друг друга не понимаем. Не можете. Можно указать что начальный адрес массивы будет с адреса кратного 4, но все char - ы в нем будут идти ПОСЛЕДОВАТЕЛЬНО и адрес последнего элемента будет N + (200000-1)
Перефразирую так. Имеем линейную память. 0,1,2,3,4,5,6,7....
Вы можете вашими директивами расположить массив чаров так, что [0] лежал в 0-й ячейке, а [1] в 4-ой ячейке ? Я утверждаю что нет

Как же , по Вашему, будут идти элементы массива, если размер каждого элемента равен 13, при установленном выравнивании (не важно какой директивой) 16?


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 17:25
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



через 13 байт. Слитно. Массива !
Будем продолжать спор, я пока что на RVDS и IAR проверил (вот дожил, очевидное проверять), и , естественно убедился, что в массиве структур никакого паддинга между элементами массива не будет
Go to the top of the page
 
+Quote Post
Demeny
сообщение Feb 8 2007, 17:31
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 648
Регистрация: 11-02-06
Из: Санкт-Петербург
Пользователь №: 14 237



Цитата(DASM @ Feb 8 2007, 17:25) *
через 13 байт. Слитно. Массива !

Попробую.


--------------------
Сделано в Китае. Упаковано в России.
Go to the top of the page
 
+Quote Post
Kail
сообщение Feb 8 2007, 18:03
Сообщение #26


Участник
*

Группа: Свой
Сообщений: 60
Регистрация: 3-08-06
Пользователь №: 19 285



Цитата(DASM @ Feb 8 2007, 17:25) *
через 13 байт. Слитно. Массива !
Будем продолжать спор, я пока что на RVDS и IAR проверил (вот дожил, очевидное проверять), и , естественно убедился, что в массиве структур никакого паддинга между элементами массива не будет

А вы смотрели на расположение в ROM или после инициализации в RAM? Насколько я понимаю в RAM с выравниваем 4, паддинг будет.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 18:07
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



я смотрел в RAM и вообще причем тут ROM-RAM. Удаляем, как не относящееся к делу
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Feb 8 2007, 19:16
Сообщение #28


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Help на Borland C++ Bulder:

"The Data Alignment options let you choose how the compiler aligns data in stored memory. Word, double word, and quad word alignment force integer-size and larger items to be aligned on memory addresses that are multiples of the type chosen. Extra bytes are inserted in structures to ensure that members align correctly.
...
Byte alignment
When byte alignment is on, the compiler does not force alignment of variables or data fields to any specific memory boundaries. The compiler aligns data at even or odd addresses, depending on the next available address.

While byte alignment produces more compact programs, the programs tend to run slower. The other data alignment options increase the speed at which 80x86 processors fetch and store data.

Word alignment (2-byte)
When word alignment is on, the compiler aligns non-character data at even addresses. Automatic and global variables are aligned properly. char and unsigned char variables and fields can be placed at any address; all others are placed at even-numbered addresses.

Double word (4-byte)
Double word alignment aligns non-character data at 32-bit word (4-byte) boundaries. Data with type sizes of less than four bytes are aligned on their type size.
....
"
и т.д.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 19:20
Сообщение #29


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



И чего ??? где тут слово array ? Я только structures вижу. Люди, кончайте дурку валять пудрить мозги говорить на разных языках, назовите мне компилятор, который решетом массив разместит
Go to the top of the page
 
+Quote Post
Alex03
сообщение Feb 8 2007, 19:22
Сообщение #30


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



По поводу игноригования младших битов адреса в ARM-е я пожалуй погорячился. Всё немного хитрее.
хитрый пример (GCC и LPC2292)

Код
typedef struct  __attribute__ ((__packed__))
{
    uchar   uc;
    uint    ui;
} test_struct_t;

test_struct_t data[5] =
{
    {'A', 0x00010203},
    {'B', 0x04050607},
    {'C', 0x08090A0B},
    {'D', 0x0C0D0E0F},
    {'E', 0x10111213}
};

void test()
{
    int n;
    uint* pui;
    uchar* puc;

    printf("sizeof(test_struct_t)=%d\n", sizeof(test_struct_t));
    printf("sizeof(data)=%d\n", sizeof(data));
    printf("sizeof(data[0])=%d\n", sizeof(data[0]));

    printf("Loop 1\n");
    for(n=0; n<5; n++)
    {
        printf("%d: %c 0x%08X %p\n", n, data[n].uc, data[n].ui, &data[n].ui);
    }

    printf("Loop 2\n");
    for(n=0; n<5; n++)
    {
        pui = &data[n].ui;
        puc = &data[n].uc;
        printf("%d: %c 0x%08X %p\n", n, *puc, *pui, pui);
    }
}


Выдаёт:
Код
sizeof(test_struct_t)=5
sizeof(data)=25
sizeof(data[0])=5


А теперь угадайте что выдают на печать первый и второй циклы?
Одно и тоже? Какбы не так:
Код
Loop 1
0: A 0x00010203 4000003d
1: B 0x04050607 40000042
2: C 0x08090A0B 40000047
3: D 0x0C0D0E0F 4000004c
4: E 0x10111213 40000051
Loop 2
0: A 0x41010203 4000003d
1: B 0x42000607 40000042
2: C 0x4304050B 40000047
3: D 0x0C0D0E0F 4000004c
4: E 0x45111213 40000051


В первом случае компилятор знает что элемент data[n].ui не (всегда) выровнен на границу слова, поэтому читает слово ЧЕТЫРМЯ!!! инструкциями ldrb, и из этих 4-х байт "собирает" слово.
Во втором случае компилятор предполагает что pui - указатель на выровненное слово и читает сразу слово командой ldr. И вот тут вылазит особенности ARMа по работе с невыравненными данными. По сути младшие 2 бита адреса слова используются как количество байт на которое циклически сдвигается прочитанное слово.


А с точки зрения голых Сей результат должен быть одинаковый.
Т.ч. ИМХО программер должен много чего знать по части платформы, компилятора и т.д.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 19:25
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



"А с точки зрения голых Сей результат должен быть одинаковый."
кто такое сказал ? Ссылку плиз
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Feb 8 2007, 19:30
Сообщение #32


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(DASM @ Feb 8 2007, 19:20) *
И чего ??? где тут слово array ? ... назовите мне компилятор, который решетом массив разместит

При чем тут array? тут даже болише написано:
Word alignment (2-byte)
When word alignment is on, ..... char and unsigned char variables and fields can be placed at _any_ address
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 19:38
Сообщение #33


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



ну а вот теперь сделайте из этих variables ARRAY - на каждый элемент будете allign писать ?? Мы говорили про ARRRAY, не надо проблемы половой жизни сусликов в условиях крайнего Севера сюда приплюсовывать уходить от темы
Go to the top of the page
 
+Quote Post
Alex03
сообщение Feb 8 2007, 19:45
Сообщение #34


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(DASM @ Feb 8 2007, 21:25) *
"А с точки зрения голых Сей результат должен быть одинаковый."
кто такое сказал ? Ссылку плиз

А почему нет то?
Пойдём от противного! Где написано что разименованный указатель на элемент структуры не обязательно равен этому элементу структуры?

да и на x86 или без __attribute__ ((__packed__)) результат вывода циклов будет одинаковый.
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 19:53
Сообщение #35


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



ладно, возможно тут и промахнулся, и тем не менее к нашим баранам вернемся, массивам то есть
Go to the top of the page
 
+Quote Post
Alex03
сообщение Feb 8 2007, 20:06
Сообщение #36


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(DASM @ Feb 8 2007, 21:53) *
ладно, возможно тут и промахнулся, и тем не менее к нашим баранам вернемся, массивам то есть

Про массивы я более придерживаюсь твоей точки зрения, т.е. выравнивание должно распрастраняться только на первый элемент массива.
Но я не буду столь категоричен, ибо .... smile.gif
Go to the top of the page
 
+Quote Post
tegumay
сообщение Feb 8 2007, 20:12
Сообщение #37


Местный
***

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



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


--------------------
;X
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 8 2007, 20:14
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



так... еще лучше.. кто глубже копнет :-D
Go to the top of the page
 
+Quote Post
gladov
сообщение Feb 8 2007, 22:18
Сообщение #39


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

Группа: Свой
Сообщений: 169
Регистрация: 10-11-05
Из: Воронеж
Пользователь №: 10 687



DASM полностью прав!!! НЕ МОЖЕТ компилятор положить массив в памяти с дырками! Это противоречит всем законам языка. Я имею полное право сделать так:
Код
uchar test[10];
void test {
    char *ptr;

    //Классический вариант:
    ptr = test + 5;  
    //А теперь так:
    ptr = (uchar*)((void*)test + 5 * sizeof(uchar));
    //И вот так:
    ptr = (uchar*)((int)test + 5 * sizeof(uchar));


Кто покажет мне (и DASM'у) хоть один компилятор, у которого эти три варианта будут не одинаковы???

Хочу сказать отдельное спасибо Alex03 за правильное предупреждение, т.к. доступ через указатель к переменной, не выровненной по умолчанию на архитектуре АРМ может работать некорректно. Я с этим еще не сталкивался, но словив такой глюк, можно долго проблемы разгребать cheers.gif
Go to the top of the page
 
+Quote Post
Andrew2000
сообщение Feb 9 2007, 01:36
Сообщение #40


Местный
***

Группа: Свой
Сообщений: 421
Регистрация: 25-12-04
Пользователь №: 1 675



Цитата(DASM @ Feb 8 2007, 19:38) *
ну а вот теперь сделайте из этих variables ARRAY - .... не надо .... уходить от темы

Как раз не ухожу, а наоборот: если уж при "Word alignment" компилятор будет "char variables and fields can be placed at _any_ address", то о каких дырах в массиве может идти речь.
(но это конкретный компилятор, допускаю, что есть специфические, может для DSP каких, где компилятору "удасться" сделать дыры, но я таких не знаю).
Go to the top of the page
 
+Quote Post
Alex03
сообщение Feb 9 2007, 07:05
Сообщение #41


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(gladov @ Feb 9 2007, 00:18) *
Хочу сказать отдельное спасибо Alex03 за правильное предупреждение, т.к. доступ через указатель к переменной, не выровненной по умолчанию на архитектуре АРМ может работать некорректно. Я с этим еще не сталкивался, но словив такой глюк, можно долго проблемы разгребать cheers.gif

Угу, cheers.gif
Мне вот интересно что выдаёт первый цикл из моего примера на других компиляторах?
Кому не лень попробуйте на всяких IAR/Keil/RVDS? Только упаковку (например pragm pack(1) вместо __attribute__ ((__packed__))) надо подправить чтобы sizeof(test_struct_t)=5 было.

Интуиция мне говорит что возможно не все компиллеры такие разборчивые в этом плане как GCC. smile.gif
Go to the top of the page
 
+Quote Post
SpiritDance
сообщение Feb 9 2007, 10:08
Сообщение #42


Дух погибшего транзистора
****

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



Блин, сразу видно - DASM вернулся на форум. Ж) Из ничего флейма на 3 странички. С возвращением! Ж))


--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
Go to the top of the page
 
+Quote Post
gladov
сообщение Feb 9 2007, 10:42
Сообщение #43


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

Группа: Свой
Сообщений: 169
Регистрация: 10-11-05
Из: Воронеж
Пользователь №: 10 687



Цитата(Alex03 @ Feb 9 2007, 07:05) *
Мне вот интересно что выдаёт первый цикл из моего примера на других компиляторах?
Кому не лень попробуйте на всяких IAR/Keil/RVDS? Только упаковку (например pragm pack(1) вместо __attribute__ ((__packed__))) надо подправить чтобы sizeof(test_struct_t)=5 было.

Интуиция мне говорит что возможно не все компиллеры такие разборчивые в этом плане как GCC. smile.gif


Проверил на ИАР 4.40а. На строки
Код
printf("%d: %c 0x%08X %p\n", n, data[n].uc, data[n].ui, &data[n].ui);
pui = &data[n].ui;


ругается так:
Warning[Pa039]: use of address of unaligned structure member

При работе, первый цикл проходит как положено, а во втором из printf вываливается в обработчик ABORT DATA. Почему тогда в первом случае работает я не понимаю blink.gif
Go to the top of the page
 
+Quote Post
DASM
сообщение Feb 9 2007, 11:19
Сообщение #44


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



да вы доки читайте ! тама написано, что это не рулез и так делать и ничего вам не гарантируется !
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 9 2007, 11:23
Сообщение #45


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(gladov @ Feb 9 2007, 09:42) *
Почему тогда в первом случае работает я не понимаю blink.gif
Здесь как раз никакого чуда. Посмотрите в листинг. Компилятор, зная, что поле структуры не выровнено, обращается к полю побайтно и из считанных байтов "склеивает" содержимое поля.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Alex03
сообщение Feb 9 2007, 12:49
Сообщение #46


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(gladov @ Feb 9 2007, 12:42) *
ругается так:
Warning[Pa039]: use of address of unaligned structure member

При работе, первый цикл проходит как положено, а во втором из printf вываливается в обработчик ABORT DATA. Почему тогда в первом случае работает я не понимаю blink.gif

Вооо. Какой процик, я так понимаю всяко не LPC.
Go to the top of the page
 
+Quote Post

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

 


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


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