Страницы

Поиск по вопросам

пятница, 12 июля 2019 г.

Как оптимизировать по размеру код на C?

Есть функция, которая выглядит примерно следующим образом: static void vParseAtResponse(char *const pcAtResponse) { if (!strcmp(pcAtResponse, CALL_READY)) { xGsmGeneralState.CallReady = TRUE; return; }
if (!strcmp(pcAtResponse, CPAS0)) { if (xGsmVoiceStatus != GSM_VOICE_NOT_ESTABLISHED) vGsmHangUp(); return; }
...
if (!strncmp(pcAtResponse, CPIN_PREFIX, _strlen(CPIN_PREFIX))) { char *pStr = pcAtResponse; pStr += strlen(CPIN_PREFIX) + 1;
if (!strcmp(pStr, READY)) { xGsmGeneralState.PinEntered = TRUE; return; } } } При этом блоков вида if (!strncmp())){} (в которых делается сравнение строк) там где сейчас многоточие порядка десятка. А теперь к сути вопроса. Вся программа очень немаленькая и при этом без указанной функции в скомпилированном виде весит ~90 КБ. Добавляю эту функцию только с одним упомянутым блоком - 93 КБ. Раскоментирую остальные блоки - 190 КБ!!! Подскажите, где тут узкое место? UPD: Компилятор GCC (платформа AVR32). Изначально все описанное происходило с уровнем оптимизации -O2. UPD2 Оптимизация -Os. Макроопределения - обычные строки типа "+CPIN:", "READY","Call Ready" Случай первый. Один блок с CALL_READY 800053d0 : 800053d0: d4 01 pushm lr 800053d2: 48 7b lddpc r11,800053ec 800053d4: f0 1f 00 07 mcall 800053f0 800053d8: c0 81 brne 800053e8 800053da: 30 19 mov r9,1 800053dc: 48 68 lddpc r8,800053f4 800053de: 48 7b lddpc r11,800053f8 800053e0: b0 89 st.b r8[0x0],r9 800053e2: 48 7c lddpc r12,800053fc 800053e4: f0 1f 00 07 mcall 80005400 800053e8: d8 02 popm pc 800053ea: 00 00 add r0,r0 800053ec: 80 00 ld.sh r0,r0[0x0] 800053ee: 70 c4 ld.w r4,r8[0x30] 800053f0: 80 00 ld.sh r0,r0[0x0] 800053f2: 63 ac ld.w r12,r1[0x68] 800053f4: 00 00 add r0,r0 800053f6: 13 90 ld.ub r0,r9[0x1] 800053f8: 80 00 ld.sh r0,r0[0x0] 800053fa: 70 d0 ld.w r0,r8[0x34] 800053fc: 80 00 ld.sh r0,r0[0x0] 800053fe: 70 dc ld.w r12,r8[0x34] 80005400: 80 00 ld.sh r0,r0[0x0] 80005402: 50 e8 stdsp sp[0x38],r8 Случай второй. 2 блока - с CALL_READY и CPIN_PREFIX: 800053d0 : 800053d0: d4 21 pushm r4-r7,lr 800053d2: 4a 2b lddpc r11,80005458 800053d4: 18 96 mov r6,r12 800053d6: f0 1f 00 22 mcall 8000545c 800053da: c0 60 breq 800053e6 800053dc: 0c 9c mov r12,r6 800053de: 30 79 mov r9,7 800053e0: 4a 0b lddpc r11,80005460 800053e2: 30 0e mov lr,0 800053e4: c1 68 rjmp 80005410 800053e6: 30 19 mov r9,1 800053e8: 49 f8 lddpc r8,80005464 800053ea: 4a 0b lddpc r11,80005468 800053ec: b0 89 st.b r8[0x0],r9 800053ee: 4a 0c lddpc r12,8000546c 800053f0: f0 1f 00 20 mcall 80005470 800053f4: d8 22 popm r4-r7,pc 800053f6: fc 0a 18 00 cp.b r10,lr 800053fa: 5f 08 sreq r8 800053fc: fc 09 18 00 cp.b r9,lr 80005400: 5f 09 sreq r9 80005402: 12 48 or r8,r9 80005404: fc 08 18 00 cp.b r8,lr 80005408: c0 d1 brne 80005422 8000540a: 2f fb sub r11,-1 8000540c: f3 d7 c0 08 bfextu r9,r7,0x0,0x8 80005410: 19 8a ld.ub r10,r12[0x0] 80005412: f2 c7 00 01 sub r7,r9,1 80005416: 2f fc sub r12,-1 80005418: 17 88 ld.ub r8,r11[0x0] 8000541a: f4 08 18 00 cp.b r8,r10 8000541e: ce c0 breq 800053f6 80005420: d8 22 popm r4-r7,pc 80005422: ec c7 ff f8 sub r7,r6,-8 80005426: 49 4b lddpc r11,80005474 80005428: 0e 9c mov r12,r7 8000542a: f0 1f 00 0d mcall 8000545c 8000542e: c0 51 brne 80005438 80005430: 30 19 mov r9,1 80005432: 48 d8 lddpc r8,80005464 80005434: b0 99 st.b r8[0x1],r9 80005436: d8 22 popm r4-r7,pc 80005438: 0e 9c mov r12,r7 8000543a: 49 0b lddpc r11,80005478 8000543c: f0 1f 00 08 mcall 8000545c 80005440: c0 b1 brne 80005456 80005442: 48 fb lddpc r11,8000547c 80005444: fe 7c 1c 00 mov r12,-58368 80005448: f0 1f 00 0e mcall 80005480 8000544c: 48 eb lddpc r11,80005484 8000544e: fe 7c 1c 00 mov r12,-58368 80005452: f0 1f 00 0c mcall 80005480 80005456: d8 22 popm r4-r7,pc 80005458: 80 00 ld.sh r0,r0[0x0] 8000545a: 70 cc ld.w r12,r8[0x30] 8000545c: 80 00 ld.sh r0,r0[0x0] 8000545e: 64 30 ld.w r0,r2[0xc] 80005460: 80 00 ld.sh r0,r0[0x0] 80005462: 70 c4 ld.w r4,r8[0x30] 80005464: 00 00 add r0,r0 80005466: 13 90 ld.ub r0,r9[0x1] 80005468: 80 00 ld.sh r0,r0[0x0] 8000546a: 70 d8 ld.w r8,r8[0x34] 8000546c: 80 00 ld.sh r0,r0[0x0] 8000546e: 70 e4 ld.w r4,r8[0x38] 80005470: 80 00 ld.sh r0,r0[0x0] 80005472: 50 e8 stdsp sp[0x38],r8 80005474: 80 00 ld.sh r0,r0[0x0] 80005476: 70 f8 ld.w r8,r8[0x3c] 80005478: 80 00 ld.sh r0,r0[0x0] 8000547a: 71 00 ld.w r0,r8[0x40] 8000547c: 80 00 ld.sh r0,r0[0x0] 8000547e: 71 08 ld.w r8,r8[0x40] 80005480: 80 00 ld.sh r0,r0[0x0] 80005482: 21 30 sub r0,19 80005484: 00 00 add r0,r0 80005486: 12 d0 st.w --r9,r0


Ответ

Комментировать больше не получается(, пишу в ответе... @alexlz - В приведенном примере в обоих блоках никаких процедур не вызывается (кроме str**). _strlen просочилась из попытки заменить ф-ции работы со строками на упрощенные самописные. Приведенный асм. листинг соответствует функциям из strig.h. Вернулся к варианту со стандартными ф-ями потому как в других модулях уже они используются и подменить их на самописный вариант руки не дошли, а так они уже размер занимают. Хотя, может стоило попробовать. UPD Нашел мое упущение, о котором не написал. Сейчас только заметил, что реально объем увеличивается при расском-ии блока, содержащего sprintf. Вот там-то собака и покопалась! Как раз эта зараза и получается под сотню КБ! По сути проблема решена. Всем спасибо.Надо только придумать как без нее строки парсить. А то у меня всего памяти 256КБ, а она!!! Чертяка

Комментариев нет:

Отправить комментарий