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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> почему char занмает 4 байта памяти, Keil, LPC2106
Kail
сообщение Dec 3 2006, 23:28
Сообщение #1


Участник
*

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



компилятор Keil
char p[16] - занимает 64 байта памяти. Смотрел в дебагере симулятора. Почему? Куда копать? В сторону aligment?

И еще вопросики про память в догонку.
У меня стек в режиме User 0x400, т.е. 1024 байт, а я объявляю int p[1000], т.е. получится 4000 байт и потом в цикле заполняю массив for (i=0;i<1000;i++)p[i]=i; симулятор доходит до p[256] и все, дальше цикл крутится, но элементы не изменяют знвчения. Вопрос, почему не генерируются ошибки доступа к памяти?
Еще один вопрос, почему стэк растет вверх? Объявляю int i; и вижу ассемблерный код STMDB R13!,[R14], после его выполнения регистр свяи содержит значение 0x400003fc (при вершине стэка 0x40000400). Почему растет вверх, а не вниз???
UND_Stack_Size EQU 0x00000004
SVC_Stack_Size EQU 0x00000004
ABT_Stack_Size EQU 0x00000004
FIQ_Stack_Size EQU 0x00000004
IRQ_Stack_Size EQU 0x00000080
USR_Stack_Size EQU 0x00000400

AREA STACK, DATA, READWRITE, ALIGN=2
DSB USR_Stack_Size ; Stack for User/System Mode
DSB SVC_Stack_Size ; Stack for Supervisor Mode
DSB IRQ_Stack_Size ; Stack for Interrupt Mode
DSB FIQ_Stack_Size ; Stack for Fast Interrupt Mode
DSB ABT_Stack_Size ; Stack for Abort Mode
DSB UND_Stack_Size ; Stack for Undefined Mode
Top_Stack:
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Dec 4 2006, 00:16
Сообщение #2


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

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Цитата
char p[16] - занимает 64 байта памяти. Смотрел в дебагере симулятора. Почему? Куда копать? В сторону aligment?

Именно туда.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 4 2006, 00:21
Сообщение #3


Гуру
******

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



Цитата(Kail @ Dec 3 2006, 23:28) *
компилятор Keil
char p[16] - занимает 64 байта памяти. Смотрел в дебагере симулятора. Почему? Куда копать? В сторону aligment?

Посмотрите лучше, что написано в map-файле.

Цитата(Kail @ Dec 3 2006, 23:28) *
У меня стек в режиме User 0x400, т.е. 1024 байт, а я объявляю int p[1000], т.е. получится 4000 байт и потом в цикле заполняю массив for (i=0;i<1000;i++)p[i]=i; симулятор доходит до p[256] и все, дальше цикл крутится, но элементы не изменяют знвчения. Вопрос, почему не генерируются ошибки доступа к памяти?

А кто, по-вашему, должен сгенерировать ошибку, и почему?

Цитата(Kail @ Dec 3 2006, 23:28) *
Еще один вопрос, почему стэк растет вверх? Объявляю int i; и вижу ассемблерный код STMDB R13!,[R14], после его выполнения регистр свяи содержит значение 0x400003fc (при вершине стэка 0x40000400). Почему растет вверх, а не вниз???

Ассемблерный код STMDB R13!,[R14] сохраняет в стеке значение LR, и к int i никакого отношения не имеет. И где это стек "растет вверх"???

Цитата(Kail @ Dec 3 2006, 23:28) *
AREA STACK, DATA, READWRITE, ALIGN=2

Для стека ALIGN должен быть 4.
Go to the top of the page
 
+Quote Post
Kail
сообщение Dec 4 2006, 01:31
Сообщение #4


Участник
*

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



int main(void)
{
char p[16],i;
for (i=0;i<16;i++)
{
p[i]=i;
}
return 0;
}
START STOP LENGTH ALIGN RELOC MEMORY CLASS SEGMENT NAME
=========================================================================
00000000H 0000010FH 00000110H 4 AT.. CODE STARTUPCODE
00000110H 00000117H 00000008H 4 UNIT CONST ?C_CLRSEG
00000118H 0000011FH 00000008H 4 UNIT CONST ?C_INITSEG
00000120H 000001D7H 000000B8H 4 UNIT CODE ?PR?main?1
000001D8H 000001DBH 00000004H 4 UNIT CODE ?C?FIQ
000001DCH 000001DFH 00000004H 4 UNIT CODE ?C?IRQ
000001E0H 000001E3H 00000004H 4 UNIT CODE ?C?DABT
000001E4H 000001E7H 00000004H 4 UNIT CODE ?C?PABT
000001E8H 000001EFH 00000008H 4 UNIT CODE ?C?UNDEF
000001F0H 3FFFFFFFH 3FFFFE10H --- --- **GAP**
40000000H 4000048FH 00000490H 4 UNIT DATA STACK


Что смотреть? Здесь только размер сегментов и их расположение в классах.



"А кто, по-вашему, должен сгенерировать ошибку, и почему?"

Должен сгенерировать симулятор, вроде этого "Memory Access violation" или должен сработать переход по вектору Pabt или Dabt..

"Ассемблерный код STMDB R13!,[R14] сохраняет в стеке значение LR, и к int i никакого отношения не имеет. И где это стек "растет вверх"???"

Я неправильно выразился, растет в направлении младших адресов. Хотя разумнее было бы сделать раст в направлении старших адресов, ведь там ОЗУ и ошибок обращения к памяти не будет. А если перейдем границу 0x40000000 то, дожны по идее генериться ошибки работы с памятью.

"Для стека ALIGN должен быть 4."
Почему? пробывал и так, и так, разницы не заметил. В книжках написано, что это ускореет работу процессора с памятью, неужели настолько критично ускоряет и как это проверить?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 4 2006, 02:43
Сообщение #5


Гуру
******

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



Цитата(Kail @ Dec 4 2006, 01:31) *
Что смотреть? Здесь только размер сегментов и их расположение в классах.

Это, в моем понимании, и не map-файл. Посмотрите, у линкера должна быть возможность генерации списка символов.

Цитата(Kail @ Dec 4 2006, 01:31) *
Должен сгенерировать симулятор, вроде этого "Memory Access violation" или должен сработать переход по вектору Pabt или Dabt..

Симулятор в общем случае не знает, где есть память, а где её нет.

Цитата(Kail @ Dec 4 2006, 01:31) *
Я неправильно выразился, растет в направлении младших адресов. Хотя разумнее было бы сделать раст в направлении старших адресов, ведь там ОЗУ и ошибок обращения к памяти не будет. А если перейдем границу 0x40000000 то, дожны по идее генериться ошибки работы с памятью.

Работа со стеком определяется стандартом ATPCS.
Компилятор не знает, в какую сторону "растет" память, и разумом пока что не обладает.

Цитата(Kail @ Dec 4 2006, 01:31) *
"Для стека ALIGN должен быть 4."
Почему? пробывал и так, и так, разницы не заметил. В книжках написано, что это ускореет работу процессора с памятью, неужели настолько критично ускоряет и как это проверить?

Книжки, наверное, по x86? ARM не может корректно работать без выравнивания.
Более того, упомянутый выше ATPCS предписывает вызывать функции с выравниванием стека по границе 8 байт.
Разницы не было заметно, так как при любом выравнивании область стека будет начинаться с 0x40000000, по крайней мере, до тех пор, пока в программе нет других сегментов данных.
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Dec 4 2006, 09:22
Сообщение #6


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

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Цитата(aaarrr @ Dec 4 2006, 00:21) *
Цитата(Kail @ Dec 3 2006, 23:28) *

AREA STACK, DATA, READWRITE, ALIGN=2

Для стека ALIGN должен быть 4.

ALIGN=2 это видимо и есть 4, т.е. выравнивание 2 в степени (ALIGN)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 4 2006, 12:02
Сообщение #7


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

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Во всех С-компиляторах есть sizeof(X) - паказывает реальный размер объекта Х.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 4 2006, 16:28
Сообщение #8


Гуру
******

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



Цитата(Alexey Bishletov @ Dec 4 2006, 09:22) *
ALIGN=2 это видимо и есть 4, т.е. выравнивание 2 в степени (ALIGN)

Нет, ALIGN задается в байтах, но должен быть степенью 2.
Go to the top of the page
 
+Quote Post
Kail
сообщение Dec 4 2006, 18:24
Сообщение #9


Участник
*

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



Всем спасибо, разобрался. Инициализированная переменная типа char во флэше занимает 1 байт, а в стеке - 4 байта, т.к. выравнивание, а вырвнивание по 4 байта, т.к. регистры 32 битные. Если например будут объевлены 3 переменные char, то они тоже буду занимать 1 ячейку стека, т.е. 3 байта и один будет пустовать. Стэк растет от старших адресов к младшим - так просто приняла ARM, по аналогии с Intel.
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Dec 5 2006, 16:32
Сообщение #10


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

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Цитата(aaarrr @ Dec 4 2006, 16:28) *
Цитата(Alexey Bishletov @ Dec 4 2006, 09:22) *

ALIGN=2 это видимо и есть 4, т.е. выравнивание 2 в степени (ALIGN)

Нет, ALIGN задается в байтах, но должен быть степенью 2.

Я забыл, что речь идет про Keil, т.е. мог и соврать (нет у меня его). Но IAR и gcc 3.ххх воспринимают ALIGN как степень для двойки.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 5 2006, 17:03
Сообщение #11


Гуру
******

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



Цитата(Alexey Bishletov @ Dec 5 2006, 15:32) *
Но IAR и gcc 3.ххх воспринимают ALIGN как степень для двойки.

Никогда никому больше этого не говорите :-).
ALIGN должен быть результатом возведения двойки в степень.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Dec 6 2006, 09:13
Сообщение #12


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

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Цитата(zltigo @ Dec 5 2006, 17:03) *
Цитата(Alexey Bishletov @ Dec 5 2006, 15:32) *

Но IAR и gcc 3.ххх воспринимают ALIGN как степень для двойки.

Никогда никому больше этого не говорите :-).
ALIGN должен быть результатом возведения двойки в степень.

Чем он должен быть я не знаю, но как факт:
Для IAR читаю в документации (EWARM_AssemblerReference.pdf)
Код
ALIGN align [,value]
...
align Exponent of the value to which the address should be aligned, in the range 0
to 30. For example, align 1 results in word alignment 2


Для gcc провожу эксперимент (в документации как-то это туманно отражено или я не то читал)
Код
  .section .text2, "ax"
  .code 32
  .align 2
lbl1:
  mov r0, #0x01

section .text2
00000000 <lbl1>:
00000000 E3A00001 mov r0, #0x1


Код
  .section .text2, "ax"
  .code 32
  .align 4
lbl1:
  mov r0, #0x01

section .text2
00000000 <lbl1>:
00000000 E3A00001 mov r0, #0x1
00000004 E1A00000 nop
00000008 E1A00000 nop
0000000C E1A00000 nop


Так как же у Keil-а?
Go to the top of the page
 
+Quote Post
Alex03
сообщение Dec 6 2006, 09:39
Сообщение #13


Местный
***

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



Цитата(Alexey Bishletov @ Dec 6 2006, 11:13) *
Для gcc провожу эксперимент (в документации как-то это туманно отражено или я не то читал)


Цитата
.align abs-expr, abs-expr, abs-expr

Pad the location counter (in the current subsection) to a particular storage boundary. The first expression (which must be absolute) is the alignment required, as described below.

The second expression (also absolute) gives the fill value to be stored in the padding bytes. It (and the comma) may be omitted. If it is omitted, the padding bytes are normally zero. However, on some systems, if the section is marked as containing code and the fill value is omitted, the space is filled with no-op instructions.

The third expression is also absolute, and is also optional. If it is present, it is the maximum number of bytes that should be skipped by this alignment directive. If doing the alignment would require skipping more bytes than the specified maximum, then the alignment is not done at all. You can omit the fill value (the second argument) entirely by simply using two commas after the required alignment; this can be useful if you want the alignment to be filled with no-op instructions when appropriate.

The way the required alignment is specified varies from system to system. For the a29k, arc, hppa, i386 using ELF, i860, iq2000, m68k, m88k, or32, s390, sparc, tic4x, tic80 and xtensa, the first expression is the alignment request in bytes. For example .align 8 advances the location counter until it is a multiple of 8. If the location counter is already a multiple of 8, no change is needed. For the tic54x, the first expression is the alignment request in words.

For other systems, including the i386 using a.out format, and the arm and strongarm, it is the number of low-order zero bits the location counter must have after advancement. For example .align 3 advances the location counter until it a multiple of 8. If the location counter is already a multiple of 8, no change is needed.

This inconsistency is due to the different behaviors of the various native assemblers for these systems which GAS must emulate. GAS also provides .balign and .p2align directives, described later, which have a consistent behavior across all architectures (but are specific to GAS).
Go to the top of the page
 
+Quote Post
zltigo
сообщение Dec 6 2006, 11:51
Сообщение #14


Гуру
******

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



Цитата(Alexey Bishletov @ Dec 6 2006, 08:13) *
Чем он должен быть я не знаю, но как факт:
Для IAR читаю в документации (EWARM_AssemblerReference.pdf)

Прочитайте еще первый пост. Речь идет о "C" для ARM платформы после чего почитайте чего там пишут в CRefrence.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Alexey Bishletov
сообщение Dec 6 2006, 15:01
Сообщение #15


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

Группа: Новичок
Сообщений: 121
Регистрация: 15-08-06
Пользователь №: 19 557



Цитата(zltigo @ Dec 6 2006, 11:51) *
Цитата(Alexey Bishletov @ Dec 6 2006, 08:13) *

Чем он должен быть я не знаю, но как факт:
Для IAR читаю в документации (EWARM_AssemblerReference.pdf)

Прочитайте еще первый пост. Речь идет о "C" для ARM платформы после чего почитайте чего там пишут в CRefrence.

Речь идет не о "С" а о startup.s для С, написаном на ASM. Собственно в самом С директива ALIGN не применима. Зачем читать CRefference?

Цитата(Alex03 @ Dec 6 2006, 09:39) *
Цитата

.align abs-expr, abs-expr, abs-expr
...
For other systems, including the i386 using a.out format, and the arm and strongarm, it is the number of low-order zero bits the location counter must have after advancement. For example .align 3 advances the location counter until it a multiple of 8. If the location counter is already a multiple of 8, no change is needed.


Спасибо за подтверждение моего эксперимента, в той документации для gcc, что идет вместе CrossStudio этой фразы я не видел.
Go to the top of the page
 
+Quote Post

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

 


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


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