본문 바로가기

시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리

kdump ( C 최적화 링크)

[IT] '리눅스 커널의 구조와 원리' 출간 후 스토리: 처절한 개발자의 현실
 
아래 포스팅에서 말씀드린 것 처럼, 이렇게 저를 뿌듯하게 하는 격려와 응원의 메시지를 받기도 했지만.
 
처절한 임베디드 개발 현실에 대한 분노와 울분의 글(댓글/이메일)도 읽게 됐습니다. 예를 들면 다음과 같은 스토리죠.
 
    * 회사에서 개발하는게 너무 힘들다. 
  군대에서 마취를 하지 않고 수술을 받아 본 적이 있는데, 그 보다 더 힘들다.
   
* 스트레스로 이빨이 흔들려 3개나 치과 치료(?)를 받았다.
 
* 선임 개발자들이 출신 학교는 물론이고 부모님 안부를 묻는 모욕적인 언사를 서슴치 않는다.
   (아마 스스로 퇴사를 유도하는게 아닌 가 싶습니다.)
 
* 집에 제대로 퇴근한 적이 없다. 6개월 동안 매일 새벽 1시 이후에 퇴근했다.
 
이런 메시지를 읽으면 마음이 조금 무거워집니다. 
제가 뭐 직접적인 도움을 줄 수도 없고, 블로그를 통해 유익한 컨텐츠를 계속 올리는 게 제가 할 수 있는 최선이라 생각이 듭니다.
 
그런데 아주 특이한 메일을 받았는데요. 하루에 3시간 밖에 잠을 자지 않고, 
책의 실습까지 다 마치고 나니 실력이 늘어 자신감이 급상승해, 면접을 보고 무사히 통과를 했다는 스토리였습니다.
이거 1년 6개월 동안 쓴 원고인데 거의 50일만에 다 읽은 독자님도 있다니. 뭔가 기를 빨린 듯한 느낌이지만 참 기분이 좋았습니다.
 
그런데 가끔, 이런 생각을 합니다.
 
    * 임베디드 개발에 진입 장벽이 높을까?
 
물론 어느 분야나 마찬가지로 고급 개발자가 되기 위한 진입 장벽이 있기 마련입니다만, 과연 임베디드 개발의 신입 개발자가 되기 위한 장벽이 있을까? 
장벽이 있다면 그 이유는 무엇일까? 저도 모르게 이런 생각이 듭니다.
 
제가 내린 결론은, 어느 정도 신입 임베디드 개발자가 되기 위한 진입 장벽이 있다는 것입니다. 
그렇다면 그 진입 장벽의 실체는 무엇인가에 대해서 이야기를 해보려고 합니다.
 
다음 포스팅에서 이 이야기를 하겠습니다. 
 
 
 
 
>>
 
[ARM] C 최적화: 함수의 반환값은 되도록 첫 번째 인자로 전달하세요.
 
ARM 함수 호출 규약예 따르면 함수가 반환하는 값은 r0에 저장됩니다.
다음 코드를 예로 들겠습니다.
 
int a;
a = proc_func();
 
proc_func() 함수가 반환되는 값은 a에 저장하는데, ARM 어셈블리 명령어로 보면 r0을 통해 a란 변수가 전달됩니다.
 
그런데 함수의 반환값은 다음에 호출하는 함수의 첫 번째 인자로 전달하면 ARM 명령어를 최적화할 수 있습니다.
 
unsigned int add_func(unsigned int x, unsigned int y)
{
    return (x + y);
}
 
void test_random_generate(void)
{
    unsigned int a = 5;
    unsigned int b = 10;
 
    unsigned int sum = 0;
 
    a = get_random_int();
    sum = add_func(a, b);
 
    printk("sum: %u n", sum);
 
    a = get_random_int();
    sum = add_func(b, a);
 
    printk("sum: %u n", sum);
}
 
    MX:FFFFFF800859E9D8|A9BF7BF3        test_random_generate:    stp     x19,x30,[SP,#-0x10]!   ; x19,x30,[SP,#-16]!
    MX:FFFFFF800859E9DC|940118DF                                 bl      0xFFFFFF80085E4D58   ; get_random_u32
    MX:FFFFFF800859E9E0|52800141                                 mov     w1,#0x0A         ; w1,#10
    MX:FFFFFF800859E9E4|97FFFFF5                                 bl      0xFFFFFF800859E9B8   ; add_func
    MX:FFFFFF800859E9E8|90002C53                                 adrp    x19,0xFFFFFF8008B26000
    MX:FFFFFF800859E9EC|912F4273                                 add     x19,x19,#0xBD0   ; x19,x19,#3024
    MX:FFFFFF800859E9F0|2A0003E1                                 mov     w1,w0
    MX:FFFFFF800859E9F4|AA1303E0                                 mov     x0,x19
    MX:FFFFFF800859E9F8|97EE5731                                 bl      0xFFFFFF80081346BC   ; printk
    MX:FFFFFF800859E9FC|940118D7                                 bl      0xFFFFFF80085E4D58   ; get_random_u32
    MX:FFFFFF800859EA00|2A0003E1                                 mov     w1,w0
    MX:FFFFFF800859EA04|52800140                                 mov     w0,#0x0A         ; w0,#10
    MX:FFFFFF800859EA08|97FFFFEC                                 bl      0xFFFFFF800859E9B8   ; add_func
    MX:FFFFFF800859EA0C|2A0003E1                                 mov     w1,w0
    MX:FFFFFF800859EA10|AA1303E0                                 mov     x0,x19
    MX:FFFFFF800859EA14|97EE572A                                 bl      0xFFFFFF80081346BC   ; printk
    MX:FFFFFF800859EA18|A8C17BF3                                 ldp     x19,x30,[SP],#0x10   ; x19,x30,[SP],#16
    MX:FFFFFF800859EA1C|D65F03C0                                 ret
 
>>
 
short sum_check_func_2(short *data)
{
        unsigned int i;
        int sum = 0;
 
        for(i = 0; i < 32; i++)
        {
            sum = *(data++);
        }
 
        return (short)sum;
}
 
ffffff800859e774 <sum_check_func_2>:
ffffff800859e774:   a9be7bfd    stp x29, x30, [sp,#-32]!
ffffff800859e778:   910003fd    mov x29, sp
ffffff800859e77c:   f9000bf3    str x19, [sp,#16]
ffffff800859e780:   aa0003f3    mov x19, x0
ffffff800859e784:   aa1e03e0    mov x0, x30
ffffff800859e788:   97ebeef5    bl  ffffff800809a35c <_mcount>
ffffff800859e78c:   aa1303e1    mov x1, x19
ffffff800859e790:   91010263    add x3, x19, #0x40
ffffff800859e794:   52800000    mov w0, #0x0                    // #0
ffffff800859e798:   78402422    ldrh    w2, [x1],#2
ffffff800859e79c:   0b020000    add w0, w0, w2
ffffff800859e7a0:   eb03003f    cmp x1, x3
ffffff800859e7a4:   13003c00    sxth    w0, w0
ffffff800859e7a8:   54ffff81    b.ne    ffffff800859e798 <sum_check_func_2+0x24>
ffffff800859e7ac:   f9400bf3    ldr x19, [sp,#16]
ffffff800859e7b0:   a8c27bfd    ldp x29, x30, [sp],#32
ffffff800859e7b4:   d65f03c0    ret
 
>>
 
ffffff800859e774 <sum_check_func_2>:
ffffff800859e774:   a9be7bfd    stp x29, x30, [sp,#-32]!
ffffff800859e778:   910003fd    mov x29, sp
ffffff800859e77c:   f9000bf3    str x19, [sp,#16]
ffffff800859e780:   aa0003f3    mov x19, x0
ffffff800859e784:   aa1e03e0    mov x0, x30
ffffff800859e788:   97ebeef5    bl  ffffff800809a35c <_mcount>
ffffff800859e78c:   91010261    add x1, x19, #0x40
ffffff800859e790:   78c02660    ldrsh   w0, [x19],#2
ffffff800859e794:   eb01027f    cmp x19, x1
ffffff800859e798:   54ffffc1    b.ne    ffffff800859e790 <sum_check_func_2+0x1c>
ffffff800859e79c:   f9400bf3    ldr x19, [sp,#16]
ffffff800859e7a0:   a8c27bfd    ldp x29, x30, [sp],#32
ffffff800859e7a4:   d65f03c0    ret