Здравствуйте, уважаемые коллеги!
Вчера глянул в листинг компилятора (arm-kgp за 2009 год) и озадачился. При том, что комплятору дан ключ -Os.
Вроде бы из простых функций, получается довольно "пухлый" код на асме.
Вот например (вначале исходник на Си, затем листинг)
CODE
/*
This function gets and sends a char
IN: nothing
OUT: received char
*/
char getChar()
{
char tmp;
while( !( U0LSR & ( 1UL << 0 ) ) );
tmp = U0RBR;
putChar( tmp );
return tmp;
}
CODE
00000788 <getChar>:
788: e59f202c ldr r2, [pc, #44]; 7bc <getChar+0x34>
78c: e5923014 ldr r3, [r2, #20]
790: e3130001 tst r3, #1; 0x1
794: e59f3020 ldr r3, [pc, #32]; 7bc <getChar+0x34>
798: 0afffffb beq 78c <getChar+0x4>
79c: e5930000 ldr r0, [r3]
7a0: e20000ff and r0, r0, #255; 0xff
7a4: e5932014 ldr r2, [r3, #20]
7a8: e3120020 tst r2, #32; 0x20
7ac: 0afffffc beq 7a4 <getChar+0x1c>
7b0: e59f3004 ldr r3, [pc, #4]; 7bc <getChar+0x34>
7b4: e5830000 str r0, [r3]
7b8: e12fff1e bx lr
7bc: e000c000 .word 0xe000c000
или вот
CODE
int64_t getNum( F_BOOT_RESULT* flag )
{
char c;
int64_t result = 0;
uint32_t negFlag = 0;
uint32_t hexFlag = 0;
*flag = F_BOOT_NO_RESULT;
while( 1 )
{
c = getChar();
if( (c == '\r') || (c == '\n'))
{
break;
}
if( c == '-' )
{
negFlag = 1;
continue;
}
if( c == 'x' )
{
hexFlag = 1;
continue;
}
if( hexFlag )
result *= 16;
else
result *= 10;
if( hexFlag )
result += hexToDec( c );
else
result += c - 0x30;
*flag = F_BOOT_OK;
}
if( negFlag )
{
result *= -1;
}
return result;
}
CODE
00000864 <getNum>:
864: e59f2104 ldr r2, [pc, #260]; 970 <getNum+0x10c>
868: e92d0ff0 push {r4, r5, r6, r7, r8, r9, sl, fp}
86c: e3a03002 mov r3, #2; 0x2
870: e3a05000 mov r5, #0; 0x0
874: e5803000 str r3, [r0]
878: e1a08005 mov r8, r5
87c: e3a03000 mov r3, #0; 0x0
880: e3a04000 mov r4, #0; 0x0
884: e1a09002 mov r9, r2
888: e3a0a00a mov sl, #10; 0xa
88c: e5921014 ldr r1, [r2, #20]
890: e3110001 tst r1, #1; 0x1
894: 0afffffc beq 88c <getNum+0x28>
898: e5921000 ldr r1, [r2]
89c: e1a0600b mov r6, fp
8a0: e20110ff and r1, r1, #255; 0xff
8a4: e1a0700c mov r7, ip
8a8: e592c014 ldr ip, [r2, #20]
8ac: e31c0020 tst ip, #32; 0x20
8b0: 0afffffc beq 8a8 <getNum+0x44>
8b4: e351000d cmp r1, #13; 0xd
8b8: 1351000a cmpne r1, #10; 0xa
8bc: e1a0b006 mov fp, r6
8c0: e1a0c007 mov ip, r7
8c4: e5891000 str r1, [r9]
8c8: 0a000020 beq 950 <getNum+0xec>
8cc: e351002d cmp r1, #45; 0x2d
8d0: 03a08001 moveq r8, #1; 0x1
8d4: 0affffec beq 88c <getNum+0x28>
8d8: e3510078 cmp r1, #120; 0x78
8dc: 03a05001 moveq r5, #1; 0x1
8e0: 0affffe9 beq 88c <getNum+0x28>
8e4: e3550000 cmp r5, #0; 0x0
8e8: 0a000003 beq 8fc <getNum+0x98>
8ec: e3510039 cmp r1, #57; 0x39
8f0: 92411030 subls r1, r1, #48; 0x30
8f4: 9a000009 bls 920 <getNum+0xbc>
8f8: ea000005 b 914 <getNum+0xb0>
8fc: e0876a93 umull r6, r7, r3, sl
900: e027749a mla r7, sl, r4, r7
904: e2411030 sub r1, r1, #48; 0x30
908: e0963001 adds r3, r6, r1
90c: e0a74fc1 adc r4, r7, r1, asr #31
910: ea00000b b 944 <getNum+0xe0>
914: e3510041 cmp r1, #65; 0x41
918: 92411037 subls r1, r1, #55; 0x37
91c: 82411057 subhi r1, r1, #87; 0x57
920: e1a06001 mov r6, r1
924: e1a07fc6 asr r7, r6, #31
928: e1a01204 lsl r1, r4, #4
92c: e1811e23 orr r1, r1, r3, lsr #28
930: e1a0c001 mov ip, r1
934: e1a01203 lsl r1, r3, #4
938: e0963001 adds r3, r6, r1
93c: e1a0b001 mov fp, r1
940: e0a7400c adc r4, r7, ip
944: e3a01000 mov r1, #0; 0x0
948: e5801000 str r1, [r0]
94c: eaffffce b 88c <getNum+0x28>
950: e3580000 cmp r8, #0; 0x0
954: 0a000001 beq 960 <getNum+0xfc>
958: e2733000 rsbs r3, r3, #0; 0x0
95c: e2e44000 rsc r4, r4, #0; 0x0
960: e1a01004 mov r1, r4
964: e1a00003 mov r0, r3
968: e8bd0ff0 pop {r4, r5, r6, r7, r8, r9, sl, fp}
96c: e12fff1e bx lr
970: e000c000 .word 0xe000c000
Я плохо понимаю язык ассемблера для ARM7TDMI-S, но мне кажется, что слишком много кода...
Вопрос трудно поставить... Но похоже, что я плохо объясняю, что нужно сделать компилятору. Нет, код работает, есть "косметические" ошибки, но поставленный алгоритм выполняется. Дело в другом. Компялтор раздувает код (или я ошибаюсь?). Вот я и озадачился вопросом, что я делаю не правильно? Может быть не те типы данных использую? Конструкции языка? Или исходный код на Си нужно выбросить, и написать более компактный, более красивый?
В общем вопрос пока пространственный... его можно было и не задавать, ведь 512К флеши есть, но, тем не менее...
Заранее спасибо за все ответы!
Выбор.