2012-10-11 2 views
-6

C++ 클래스의 데이터 구조는 무엇입니까? 어셈블리 수준에서 어떻게 작동합니까?클래스의 데이터 구조

IF 문은 코드 행의 compare + 조건부 점프입니다.

배열 및 문자열은 데이터의 체인 링크입니다.

+4

정확히 무엇을 요구하고 있습니까? – IronMan84

+2

'if' ≠'jump'. 적어도 if = compare와 + 조건부 점프. 클래스는 일반적으로 데이터, 클래스의 가상 메소드에 대한 포인터 및 클래스의 상위 클래스 (있는 경우)에 대한 포인터 (파생 된 위치)를 포함하는 데이터 구조입니다. –

+0

C++ 클래스의 데이터 구조 란 무엇입니까? – wizztjh

답변

3

컴파일러는 모든 회원에게 오프셋을 할당하고, 회원의 모든로드/저장 작업에 다음을 포함한다 :

struct foo { 
    uint32_t bar; 
    uint32_t baz; 

    uint32_t get_baz() { return baz; } 
}; 

uint32_t get_baz_from_foo(foo *f) { return f->baz; } 

이된다 (단순에 사용되는 ARM 어셈블러 코드) :

foo__get_baz: 
    ; calling convention: this pointer in r3 
    ; load 32 bit value from r3 + 4 bytes into r0 
    ldr r0, [r3, #4]; 
    ; calling convention: return value in r0 
    ; return from subroutine 
    b lr 

get_baz_from_foo: 
    ; calling convention: first parameter in r0 
    ; load 32 bit value from r0 + 4 bytes into r0 
    ldr r0, [r0, #4] 
    ; calling convention: return value in r0 
    ; return from subroutine 
    b lr 

struct를로를 각각의 class 레이아웃은 컴파일 후에 변경되지 않고, 4는 여기서 명령어 스트림으로 하드 코딩됩니다.

struct foo2 { 
    foo2() : bar(5), baz(7) { } 
    uint32_t bar; 
    uint32_t baz; 
    uint32_t get_baz() { return baz; } 
}; 

우리는 끝 생성자가있는 경우

new__foo: 
    ; two 32 bit integers need 8 bytes 
    ; calling convention: first parameter in r0 
    mov r0, #8 
    ; call allocator, which will then return to the function invoking new 
    bra malloc 

: 인스턴스를 생성

메모리를 할당하고, 구조체에 대한 포인터를 기대하고 모든 사람에게 할당 함수에서 포인터를 전달하여 작동 (코멘트없이 알아낼 수 있어야하는) 오브젝트를 생성하는 약간 더 복잡한 방법을 사용하십시오 :

new__foo2: 
    strdb lr, ![sp] 
    mov r0, #8 
    bl malloc 
    mov r1, #5 
    str r1, [r0] 
    mov r1, #7 
    str r1, [r0, #4] 
    ldaia lr, ![sp] 
    b lr 

구현은 foo 클래스의 경우와 동일합니다.

은 지금은 이러한 개체를 생성하고 바즈 값을 얻을 경우 :

bl new__foo2 
    ; remember: the this pointer goes to r3 
    mov r3, r0 
    bl foo2__get_baz 

내가 값 7을 포함 r0로 끝날합니다. 기능 테이블에 대한 포인터를 인 숨겨진 데이터 부재가 생성 virtual 메소드

, :

struct base { 
    virtual uint32_t get_baz() = 0; 
}; 

struct derived : base { 
    derived() : baz(5) { } 
    virtual uint32_t get_baz(); 
    uint32_t bar; 
    uint32_t baz; 
}; 

이 함수를 호출

new__derived: 
    strdb lr, ![sp] 
    mov r0, #12 
    bl malloc 
    mov r1, #5 
    str r1, [r0, #8] 
    ; get the address of the vtable 
    ldr r1, =vtable__derived 
    ; vtable typically goes to the end of the class defining it 
    ; as this is the base class, it goes before derived's data members 
    str r1, [r0] 
    ldria lr, ![sp] 
    b lr 

vtable__derived: 
    ; pointer to function 
    dw derived__get_baz 

derived__get_baz: 
    ldr r0, [r3, #8] 
    b lr 

된다 간접적으로 수행된다 :

; construct normally 
    bl new__derived 
    ; here, we forget that this is a "derived" object 
    ; this pointer to r3 
    mov r3, r0 
    ; get vtable ptr 
    ldr r0, [r3] 
    ; get function ptr from vtable 
    ldr r0, [r0] 
    ; call function 
    bl r0 

여기에서 r0은입니다. 그것이 생성자가 거기에 저장된 것이기 때문에입니다.