There is a function that looks something like this:

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; } } } 

At the same time, blocks of the form if (!strncmp())){} (in which a string comparison is made) are where there are now dots of the order of ten.

And now to the point. The whole program is very rather big and at the same time without the specified function in compiled form weighs ~ 90 KB. I add this function with only one block mentioned - 93 KB. I will comment on the remaining blocks - 190 KB !!! Tell me, where is the bottleneck?

UPD: GCC compiler (AVR32 platform). Initially, everything described happened with the optimization level -O2. UPD2 Optimization -Os. Macros - ordinary strings like "+ CPIN:", "READY", "Call Ready"

The first case. One block with CALL_READY

 800053d0 <vParseAtResponse>: 800053d0: d4 01 pushm lr 800053d2: 48 7b lddpc r11,800053ec <vParseAtResponse+0x1c> 800053d4: f0 1f 00 07 mcall 800053f0 <vParseAtResponse+0x20> 800053d8: c0 81 brne 800053e8 <vParseAtResponse+0x18> 800053da: 30 19 mov r9,1 800053dc: 48 68 lddpc r8,800053f4 <vParseAtResponse+0x24> 800053de: 48 7b lddpc r11,800053f8 <vParseAtResponse+0x28> 800053e0: b0 89 st.b r8[0x0],r9 800053e2: 48 7c lddpc r12,800053fc <vParseAtResponse+0x2c> 800053e4: f0 1f 00 07 mcall 80005400 <vParseAtResponse+0x30> 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 

Case two. 2 blocks - with CALL_READY and CPIN_PREFIX:

 800053d0 <vParseAtResponse>: 800053d0: d4 21 pushm r4-r7,lr 800053d2: 4a 2b lddpc r11,80005458 <vParseAtResponse+0x88> 800053d4: 18 96 mov r6,r12 800053d6: f0 1f 00 22 mcall 8000545c <vParseAtResponse+0x8c> 800053da: c0 60 breq 800053e6 <vParseAtResponse+0x16> 800053dc: 0c 9c mov r12,r6 800053de: 30 79 mov r9,7 800053e0: 4a 0b lddpc r11,80005460 <vParseAtResponse+0x90> 800053e2: 30 0e mov lr,0 800053e4: c1 68 rjmp 80005410 <vParseAtResponse+0x40> 800053e6: 30 19 mov r9,1 800053e8: 49 f8 lddpc r8,80005464 <vParseAtResponse+0x94> 800053ea: 4a 0b lddpc r11,80005468 <vParseAtResponse+0x98> 800053ec: b0 89 st.b r8[0x0],r9 800053ee: 4a 0c lddpc r12,8000546c <vParseAtResponse+0x9c> 800053f0: f0 1f 00 20 mcall 80005470 <vParseAtResponse+0xa0> 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 <vParseAtResponse+0x52> 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 <vParseAtResponse+0x26> 80005420: d8 22 popm r4-r7,pc 80005422: ec c7 ff f8 sub r7,r6,-8 80005426: 49 4b lddpc r11,80005474 <vParseAtResponse+0xa4> 80005428: 0e 9c mov r12,r7 8000542a: f0 1f 00 0d mcall 8000545c <vParseAtResponse+0x8c> 8000542e: c0 51 brne 80005438 <vParseAtResponse+0x68> 80005430: 30 19 mov r9,1 80005432: 48 d8 lddpc r8,80005464 <vParseAtResponse+0x94> 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 <vParseAtResponse+0xa8> 8000543c: f0 1f 00 08 mcall 8000545c <vParseAtResponse+0x8c> 80005440: c0 b1 brne 80005456 <vParseAtResponse+0x86> 80005442: 48 fb lddpc r11,8000547c <vParseAtResponse+0xac> 80005444: fe 7c 1c 00 mov r12,-58368 80005448: f0 1f 00 0e mcall 80005480 <vParseAtResponse+0xb0> 8000544c: 48 eb lddpc r11,80005484 <vParseAtResponse+0xb4> 8000544e: fe 7c 1c 00 mov r12,-58368 80005452: f0 1f 00 0c mcall 80005480 <vParseAtResponse+0xb0> 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 
  • 2
    Why not try to consistently uncomment if blocks and look at the resulting size, simultaneously looking at the assembler listing generated by the compiler? - fogbit
  • one
    In such matters, be sure to say which compiler and OS are. And so, try to play around with the compiler optimization level. In general, by the appearance of these blocks, it doesn’t pull into kilobytes. Riddle. About these minuses. It looks like some kind of inadequate wound up. Not the first such negative see. It seems he is minus what he himself does not understand. - avp
  • one
    @avp, the next step in this kind of narcissism is to resent why the damned inadequate do not vote FOR :-) Minus mine, in the light of recent edits, you could have removed it, but then your comment will lose all value :-) By the way, it’s still not clear what exactly the code generator adds to each comparison. - karmadro4
  • one
    Stupid and not thin. - avp
  • one
    Interestingly, the one who wished listing, is familiar with architecture of avr32? (me not). And due to what is obtained 300-400 bytes? At the expense of called procedures from if-blocks, which the linker throws out, if the calls are commented out? - alexlz

1 answer 1

Commenting is no longer possible (I am writing in response ...

@alexlz - In the above example, no procedure is called in both blocks (except for str **). _strlen leaked from an attempt to replace the functions of working with strings with simplified self-written ones. Given asm. the listing corresponds to the functions from strig.h . I returned to the version with standard f-yami because in other modules they are already used and they did not reach the samopisny version of the hand, and so they already occupy the size. Although it might be worth a try.

UPD Found my omission about which did not write. Now I just noticed that the actual volume increases with the dissection of the block containing sprintf. That's where the dog and rummaged! Just this infection and it turns out under a hundred KB! In fact, the problem is solved. Thank you all. You just have to figure out how to parse strings without it. And then I have all the memory 256K, and she !!! Devil

  • Well, great. And I (AVR32 do not know) just looked at the addresses, found that the difference in 132 bytes and decided to report it (in the sense that these blocks had nothing to do with it). I look, and the topic has been updated, you have already decided everything! - avp
  • one
    Does she have truncation capabilities? Well, for example, chop off floating arithmetic? Or ask Google? There are a lot of bells and whistles, and of them, most likely, a small amount is required. (I looked at the edge of my ear, like some recommendations should be in stdio.h. I do not have avr-libc) I have avr-libc for avr8, there is a recommendation -Wl, -u, vfprintf -lprintf_min So you have it for avr32 or not - I don't know - alexlz
  • Regarding the sprintf. Probably the easiest way to get the source from the GNU libc and throw away all unnecessary. - avp