|
почему char занмает 4 байта памяти, Keil, LPC2106 |
|
|
|
Dec 3 2006, 23:28
|
Участник

Группа: Свой
Сообщений: 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:
|
|
|
|
|
Dec 4 2006, 00:21
|
Гуру
     
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Dec 4 2006, 01:31
|
Участник

Группа: Свой
Сообщений: 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." Почему? пробывал и так, и так, разницы не заметил. В книжках написано, что это ускореет работу процессора с памятью, неужели настолько критично ускоряет и как это проверить?
|
|
|
|
|
Dec 4 2006, 02:43
|
Гуру
     
Группа: Свой
Сообщений: 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, по крайней мере, до тех пор, пока в программе нет других сегментов данных.
|
|
|
|
|
Dec 4 2006, 09:22
|
Частый гость
 
Группа: Новичок
Сообщений: 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)
|
|
|
|
|
Dec 4 2006, 18:24
|
Участник

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

|
Всем спасибо, разобрался. Инициализированная переменная типа char во флэше занимает 1 байт, а в стеке - 4 байта, т.к. выравнивание, а вырвнивание по 4 байта, т.к. регистры 32 битные. Если например будут объевлены 3 переменные char, то они тоже буду занимать 1 ячейку стека, т.е. 3 байта и один будет пустовать. Стэк растет от старших адресов к младшим - так просто приняла ARM, по аналогии с Intel.
|
|
|
|
|
Dec 5 2006, 16:32
|
Частый гость
 
Группа: Новичок
Сообщений: 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 как степень для двойки.
|
|
|
|
|
Dec 5 2006, 17:03
|

Гуру
     
Группа: Свой
Сообщений: 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
|
|
|
|
|
Dec 6 2006, 09:13
|
Частый гость
 
Группа: Новичок
Сообщений: 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-а?
|
|
|
|
|
Dec 6 2006, 09:39
|
Местный
  
Группа: Свой
Сообщений: 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).
|
|
|
|
|
Dec 6 2006, 15:01
|
Частый гость
 
Группа: Новичок
Сообщений: 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 этой фразы я не видел.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|