어 셈 블 리 에서 c++의 기본 구조 함수 사용 분석

c++의 원본 프로그램:

class X {
private:
    int i;
};

int main() {
    X x;
}

위의 클래스 X 는 구조 함 수 를 정의 하지 않 고 int i 만 있 습 니 다.
다음은 어 셈 블 리 프로그램 입 니 다.

; 7    : int main() {

    push    ebp;ebp , , , , ,
    mov    ebp, esp; main ebp , ebp main
    push    ecx; ecx , esp 4byte
               ; , 4byte , ecx

; 8    :     X x;
; 9    : }

    xor    eax, eax;eax ,
    mov    esp, ebp; push ecx , 4byte
    pop    ebp; main
    ret    0;

어 셈 블 리 를 통 해 push ecx 를 통 해 컴 파일 러 는 스 택 지붕 을 4byte 로 이동 시 키 고 레지스터 의 ecx 값 을 기록 합 니 다.클래스 X 는 하나의 int 만 포함 하고 크기 는 4byte 이기 때문에 이 문장 은 대상 x 에 공간 을 분배 하 는 것 으로 볼 수 있 습 니 다.그 다음 에는 이 구역 을 적당 하 게 초기 화하 기 위해 함수 호출 이 없습니다.따라서 구조 함 수 를 명확 하 게 정의 하지 않 았 을 때 초기 화 작업 이 없습니다.
다음은 c++프로그램 을 살 펴 보 겠 습 니 다.

class X {
private:
    int i;
    int j;// int j
};

int main() {
    X x;
}

위 에 비해 클래스 X 에 구성원 변수 int j 를 추 가 했 고 클래스 의 크기 는 8 바이트 로 변 했 습 니 다.
다음은 대응 하 는 외환 인 코딩 입 니 다.

; 8    : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 8; 8byte, X

; 9    :     X x;
; 10   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

외환 인 코딩 을 통 해 알 수 있 듯 이 sub esp,8 명령 을 통 해 스 택 은 8byte 의 공간 을 남 겼 습 니 다.클래스 X 의 크기 와 같 습 니 다.마찬가지 로 어떠한 함수 도 호출 하지 않 고 초기 화 작업 을 합 니 다.
따라서 다시 말하자면 구조 함 수 를 명확 하 게 정의 하지 않 았 을 때 컴 파일 러 는 어떠한 함수 호출 도 초기 화 작업 을 하지 않 고 스 택 꼭대기 에 대상 을 남 기 는 데 필요 한 공간 만 남 겼 다.즉,이런 상황 에서 컴 파일 러 는 묵인 적 인 구조 함 수 를 제공 하지 않 는 다.
그렇다면 책 에서 말 하 는 컴 파일 러 가 기본 적 인 구조 함 수 를 제공 하 는 것 은 어떻게 된 일 일 까?
다음은 첫 번 째 상황 을 보 겠 습 니 다.클래스 안에 가상 구성원 함수 가 있 습 니 다.
c+소스 코드 는 다음 과 같 습 니 다.

class X {
private:
    int i;
    int j;// int j
public:
    virtual ~X() {

    }
};


int main() {
    X x;
}

분석 함 수 는 가상 함수 입 니 다.
다음은 main 함수 에 대응 하 는 외환 인 코딩 입 니 다.

; 13   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; x 12byte , int i,int j 8byte, , vptr 4byte

; 14   :     X x;

    lea    ecx, DWORD PTR _x$[ebp]; x , ecx
    call    ??0X@@QAE@XZ; x

; 15   : }

    lea    ecx, DWORD PTR _x$[ebp]; x
    call    ??1X@@UAE@XZ                ;
    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

대상 x 의 구조 함수 가 호출 되 었 고 컴 파일 러 는 기본 적 인 구조 함 수 를 합성 한 것 을 볼 수 있 습 니 다.
다음은 구조 함수 의 외환 인 코딩 입 니 다.

??0X@@QAE@XZ PROC                    ; X::X, COMDAT
; _this$ = ecx
    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx;ecx x
    mov    eax, DWORD PTR _this$[ebp]; x eax
    mov    DWORD PTR [eax], OFFSET ??_7X@@6B@; vptr , vtable (OFFSET ??_7X@@6B@ vtable )
                                          ; , vptr
    mov    eax, DWORD PTR _this$[ebp]
    mov    esp, ebp
    pop    ebp
    ret    0
에서 볼 수 있 습 니 다.가상 함수 가 있 기 때문에 구조 함수 가 vptr 지침 을 초기 화 했 지만 다른 두 변수 int i,int j 에 값 을 부여 하지 않 았 습 니 다.
위 에서 알 수 있 듯 이 클래스 에 가상 함수 가 포함 되 어 있 을 때 구조 함 수 를 명확 하 게 정의 하지 않 았 을 때 컴 파일 러 는 우리 에 게 기본 적 인 구조 함 수 를 제공 할 것 이다.따라서 하나의 유형 이 허 기 류 를 계승 할 때 도 위의 상황 을 만족시킨다.
다음은 두 번 째 상황 입 니 다.클래스 Y 는 클래스 X 를 계승 하고 X 는 기본 적 인 구조 함수(컴 파일 러 가 제공 하 는 것 이 아니 라)를 명 확 히 정 의 했 습 니 다.클래스 Y 는 그 어떠한 구조 함수 도 정의 하지 않 습 니 다.
먼저 c+소스 코드 를 보 겠 습 니 다.

class X {
private:
    int i;
    int j;
public:
    X() {//X
        i = 0;
        j = 1;
    }
};

class Y : public X{//Y X
private:
    int i;
};


int main() {
    Y y;
}

클래스 Y 에는 구조 함수 가 정의 되 어 있 지 않 습 니 다.
다음은 main 함수 에 대응 하 는 외환 인 코딩 입 니 다.

; 19   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; y 12byte ,y int i 4byte int i int j 8byte

; 20   :     Y y;

    lea    ecx, DWORD PTR _y$[ebp]; y , ecx
    call    ??0Y@@QAE@XZ; y

; 21   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

main 함수 에서 컴 파일 러 가 제공 하 는 기본 y 대상 의 기본 구조 함 수 를 호출 하 였 습 니 다.
 다음은 컴 파일 러 가 제공 하 는 y 대상 의 기본 구조 함수 의 어 셈 블 리 인 코딩 입 니 다.

??0Y@@QAE@XZ PROC                    ; Y::Y, COMDAT
; _this$ = ecx
    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx;ecx y
    mov    ecx, DWORD PTR _this$[ebp]
    call    ??0X@@QAE@XZ                ; X
    mov    eax, DWORD PTR _this$[ebp]
    mov    esp, ebp
    pop    ebp
    ret    0
??0Y@@QAE@XZ ENDP
Y 대상 의 구조 함수 가 부모 클래스 의 구조 함 수 를 호출 하여 부모 클래스 를 계승 하 는 구성원 변 수 를 초기 화 하 는 것 을 볼 수 있 지만 자신의 구성원 변 수 는 초기 화 되 지 않 았 습 니 다.
다음은 부 류 X 의 구조 함수 인 코딩 입 니 다.

; 7    :     X() {

    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx; ecx y

; 8    :         i = 0;

    mov    eax, DWORD PTR _this$[ebp]; y eax
    mov    DWORD PTR [eax], 0; i

; 9    :         j = 1;

    mov    ecx, DWORD PTR _this$[ebp]; y ecx
    mov    DWORD PTR [ecx+4], 1; j, y , 8 , 4byte
                            ; i, y 4byte, j

; 10   :     }

    mov    eax, DWORD PTR _this$[ebp]
    mov    esp, ebp
    pop    ebp
    ret    0

에서 볼 수 있 듯 이 y 대상 이 부 류 를 계승 하 는 구성원 변 수 는 부 류 구조 함수 에서 초기 화 됩 니 다.부모 대상 은 하위 대상 에 포함 되 어 있 으 며,this 지침,즉 레지스터 ecx 가 저장 하 는 첫 번 째 주 소 는 항상 하위 대상 y 의 첫 번 째 주소 입 니 다.
부모 클래스 X 에서 도 구조 함수 가 정의 되 지 않 았 다 면 어떻게 되 었 을 까?
다음은 c+소스 코드:

class X {
private:
    int i;
    int j;

   
};

class Y : public X{//Y X
private:
    int i;
};


int main() {
    Y y;
}

부모 클래스 와 하위 클래스 는 구조 함수 가 없습니다.
다음은 main 함수 외환 인 코딩 입 니 다.

; 16   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; , y 12byte

; 17   :     Y y;
; 18   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

main 에 함수 호출 이 전혀 없 는 것 을 볼 수 있 습 니 다.즉,컴 파일 러 는 하위 대상 y 에 기본 구조 함 수 를 제공 하지 않 았 습 니 다.
그렇다면 부모 클래스 에 매개 변 수 를 가 진 구조 함수 가 있 고 하위 클래스 에 구조 함수 가 없다 면?이 럴 때 컴 파일 러 가 틀 릴 수 있다.
다음은 세 번 째 상황 을 보 겠 습 니 다.클래스 Y 에는 구성원 대상 X 가 포함 되 어 있 고 구성원 대상 은 정 의 된 기본 구조 함수 가 있 으 며 클래스 Y 에는 구조 함수 가 없습니다.
먼저 c++소스 코드:

; 16   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; , y 12byte

; 17   :     Y y;
; 18   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

클래스 X 는 클래스 Y 의 구성원 대상 이 고 다음은 main 함수 의 어 셈 블 리 코드 입 니 다.

; 21   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; y 12byte 8byte y 4byte y

; 22   :     Y y;

    lea    ecx, DWORD PTR _y$[ebp]; y ecx
    call    ??0Y@@QAE@XZ; y ,

; 23   : }

    xor    eax, eax
    mov    esp, ebp

    pop    ebp
    ret    0

대상 y 의 구조 함수 가 호출 되 었 습 니 다.즉,컴 파일 러 는 기본 적 인 구조 함 수 를 제공 합 니 다.
대상 y 의 구조 함수 외환 인 코딩:

??0Y@@QAE@XZ PROC                    ; Y::Y, COMDAT
; _this$ = ecx
    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx;ecx y
    mov    ecx, DWORD PTR _this$[ebp]
    add    ecx, 4; 4 y i
    call    ??0X@@QAE@XZ                ; x
    mov    eax, DWORD PTR _this$[ebp]
    mov    esp, ebp
    pop    ebp
    ret    0
대상 y 의 구조 함 수 는 구성원 대상 x 의 구조 함 수 를 호출 하여 구성원 대상 중의 구성원 변 수 를 초기 화하 고 대상 y 자체 의 구성원 변 수 는 초기 화 되 지 않 았 습 니 다.
구성원 대상 x 의 구조 함수 외환 코드:

??0X@@QAE@XZ PROC                    ; X::X, COMDAT
; _this$ = ecx

; 7    :     X() {

    push    ebp
    mov    ebp, esp
    push    ecx
    mov    DWORD PTR _this$[ebp], ecx;ecx x

; 8    :         i = 0;

    mov    eax, DWORD PTR _this$[ebp]; x eax
    mov    DWORD PTR [eax], 0; x i

; 9    :         j = 0;

    mov    ecx, DWORD PTR _this$[ebp]; x ecx
    mov    DWORD PTR [ecx+4], 0; x j 4 j x 4byte( x i )

; 10   :     }

    mov    eax, DWORD PTR _this$[ebp]
    mov    esp, ebp
    pop    ebp
    ret    0

그러나 구성원 대상 x 에 도 구조 함수 가 없다 면 상황 은 어 떨 까?
다음은 c++소스 코드:

class X {
private:
    int i;
    int j;

   
};

class Y {
private:
    int i;
    X x;//x
};


int main() {
    Y y;
}

다음은 main 함수 외환 코드 입 니 다.

; 17   : int main() {

    push    ebp
    mov    ebp, esp
    sub    esp, 12                    ; 12byte

; 18   :     Y y;
; 19   : }

    xor    eax, eax
    mov    esp, ebp
    pop    ebp
    ret    0

메 인 함수 에는 함수 호출 이 없습니다.즉,컴 파일 러 는 기본 구조 함 수 를 제공 하지 않 았 습 니 다.
만약 에 구성원 대상 x 에 인자 가 있 는 구조 함수(즉,기본 구조 함수 가 아 닌)가 있 고 대상 y 에 구조 함수 가 없다 면?이때 컴 파일 러 는 잘못 보고 할 것 이다.
이런 상황 은 앞의 상황 과 매우 비슷 하 다.
이상 의 상황 을 종합 하면 하나의 유형 에 대해 어떠한 구조 함수 도 포함 하지 않 고 컴 파일 러 는 기본 적 인 구조 함 수 를 제공 하 며 세 가지 상황 이 있다.
1 클래스 자체 함수 가상 구성원 함수 또는 가상 기본 클래스 계승
2 류 의 기본 클래스 는 구조 함수 가 있 고 기본 구조 함수 가 정 의 된 기본 구조 함수(비 컴 파일 러 제공)를 표시 합 니 다.만약 에 기본 클래스 의 구조 함수 가 매개 변수(즉,비 기본 구조 함수)를 가지 고 있 으 면 컴 파일 러 가 잘못 보고 합 니 다.
3  이러한 상황 은 이전 과 비슷 합 니 다.클래스 의 구성원 대상 은 구조 함수 가 있 고 구성원 대상 의 구조 함 수 는 정 의 된 기본 구조 함수(비 컴 파일 러 제공)를 표시 합 니 다.구성원 대상 의 구조 함수 에 인자(즉,기본 구조 함수 가 아 닌)가 있 으 면 컴 파일 러 가 잘못 되 었 습 니 다.
 
이상 에서 의 지식 포 인 트 를 참고 하고 자신의 분석 도 있 습 니 다.지적 을 환영 합 니 다.

좋은 웹페이지 즐겨찾기