У меня есть программа C в файле delay.c
:
void delay(int num)
{
volatile int i;
for(i=0; i<num; i++);
}
Затем я компилирую программу с помощью gcc 4.6.3 на эмуляторе ARM (точнее, armel) с помощью команды gcc -g -O1 -o delay.o delay.c
. Сборка в delay.o
такая:
00000000 <delay>:
0: e24dd008 sub sp, sp, #8
4: e3a03000 mov r3, #0
8: e58d3004 str r3, [sp, #4]
c: e59d3004 ldr r3, [sp, #4]
10: e1500003 cmp r0, r3
14: da000005 ble 30 <delay+0x30>
18: e59d3004 ldr r3, [sp, #4]
1c: e2833001 add r3, r3, #1
20: e58d3004 str r3, [sp, #4]
24: e59d3004 ldr r3, [sp, #4]
28: e1530000 cmp r3, r0
2c: bafffff9 blt 18 <delay+0x18>
30: e28dd008 add sp, sp, #8
34: e12fff1e bx lr
Я хочу выяснить, где находится переменная i
в стеке функции delay
из отладочной информации. Ниже представлена информация о delay
и i
в разделе .debug_info
:
<1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
<26> DW_AT_external : 1
<27> DW_AT_name : (indirect string, offset: 0x19): delay
<2b> DW_AT_decl_file : 1
<2c> DW_AT_decl_line : 1
<2d> DW_AT_prototyped : 1
<2e> DW_AT_low_pc : 0x0
<32> DW_AT_high_pc : 0x38
<36> DW_AT_frame_base : 0x0 (location list)
<3a> DW_AT_sibling : <0x59>
...
<2><4b>: Abbrev Number: 4 (DW_TAG_variable)
<4c> DW_AT_name : i
<4e> DW_AT_decl_file : 1
<4f> DW_AT_decl_line : 3
<50> DW_AT_type : <0x60>
<54> DW_AT_location : 0x20 (location list)
Он показывает, что местоположение i
находится в списке местоположений. Итак, я вывожу список местоположений:
Offset Begin End Expression
00000000 00000000 00000004 (DW_OP_breg13 (r13): 0)
00000000 00000004 00000038 (DW_OP_breg13 (r13): 8)
00000000 <End of list>
00000020 0000000c 00000020 (DW_OP_fbreg: -12)
00000020 00000024 00000028 (DW_OP_reg3 (r3))
00000020 00000028 00000038 (DW_OP_fbreg: -12)
00000020 <End of list>
Для адресов с 4 по 38 основание кадра delay
должно быть r13 + 8
. Таким образом, от адреса c до 20 и от адреса 28 до 38 местоположение i
равно r13 + 8 -12 = r13 - 4
.
Однако из сборки мы можем узнать, что места r13 - 4
нет, а i
, по-видимому, находится в месте r13 + 4
.
Я пропустил какой-то шаг расчета? Кто-нибудь может объяснить разницу в местоположении i
между расчетом из отладочной информации и в сборке?
Заранее спасибо!