ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Compilation of C++ to binary
    Computer/Programming 2008. 1. 11. 15:41
    array 사용이 컴파일되었을 때의 모양
    일반적인 local variable의 경우
        mov [ebp+var_38], 0    ; i = 0
    과 같이 ebp 레지스터에 대한 상대 위치를 이용하여 표현한다.
    array도 마찬가지인데
        mov [ebp+eax*4+var_2C], ecx   ; a[i] = i;
    과 같이 ebp에 대한 상대 위치로 표현한다.
    MOV r/m32, r32
    MOV r32, r/m32
    MOV r32, imm32
    같은 instruction을 사용한다.
    stack guard 같은 것을 사용하려면 첫번째 argument가 r/m32인 것만 찾으면 되는 것일까?


    function pointer가 컴파일되었을 때의 모양
    function pointer 값을 배열에 assign할 때
        fp[0] = &a;    // c++

        move [ebp+var_14], offset loc_4110F5
    와 같이 컴파일되는 것을 볼 수 있다.
    function을 call할 때
        (*fp[i])();   // c++

        move ecx, [ebp_eax*4+var_14]
        call ecx
    와 같이 컴파일되는 것을 볼 수 있다.

    즉 assign할 때는 location 값이 그대로 들어가고,
    call할 때는 register에 location을 넣고 그대로 jump한다.

    import한 function에 대한 call이 compile되는 경우 (VS2005)
    DS / SS / CS (DS:data segment / SS:stack segment / CS:code segment)
        call    ds:__imp__scanf
    의 경우 ds는 data segment를 가르키고,
    __imp__scanf가 data segment 안에 있는 주소를 가리키는 offset이 된다.

    전에 VS98로 compile할 때는
    prinf같은 메소드들도 embed되었던 것 같다.


    switch문의 경우 switch 갯수가 몇 개 되지 않을 때는 cmp를 이용하여 그대로 compile되지만,
    갯수가 많을 때는
    1. default(가장 큰 숫자보가 크다면 jmp) cmp / ja 형태로 컴파일되며
    2. 나머지는 table에 만들어 넣는다. 1 byte이기 때문에 많아야 255개인데, default를 빼고 나머지에 대해서만 table을 만들어서 해당되는 숫자에 대한 주소를 그대로 읽어오고 그 곳으로 jump하는 식이다. vs 2005에서는 table이 text section 뒤에 붙어 있었다. 즉 code와 data가 mix되어 text section에 있던 것이다.

    .text:00413779                 mov     eax, [ebp+var_8]
    .text:0041377C                 mov     [ebp+var_D0], eax
    .text:00413782                 cmp     [ebp+var_D0], 5Fh
    .text:00413789                 ja      loc_4138C2
    .text:0041378F                 mov     ecx, [ebp+var_D0]
    .text:00413795                 movzx   edx, ds:byte_413954[ecx]
    .text:0041379C                 jmp     ds:off_413920[edx*4]
    .text:004137A3
    .text:004137A3 loc_4137A3:                             ; DATA XREF: .text:off_413920o
    .text:004137A3                 mov     esi, esp
    .text:004137A5                 push    offset aA_0     ; "a"
    .text:004137AA                 call    ds:__imp__printf
    .text:004137B0                 add     esp, 4
    .text:004137B3                 cmp     esi, esp
    .text:004137B5                 call    j__RTC_CheckEsp
    .text:004137BA
    .text:004137BA loc_4137BA:                             ; CODE XREF: wmain+5Cj
    .text:004137BA                                         ; DATA XREF: .text:00413924o
    .text:004137BA                 mov     esi, esp
    .text:004137BC                 push    offset aA       ; "a"
    .text:004137C1                 call    ds:__imp__printf
    .text:004137C7                 add     esp, 4
    .text:004137CA                 cmp     esi, esp
    .text:004137CC                 call    j__RTC_CheckEsp

    이정도가 예제가 될듯


    virtual call이 compile되는 경우
    switch ~ case와 마찬가지로  table이 만들어져서,
    해당하는 function으로 jump하도록 하고 있다.
Designed by Tistory.