现在的位置: 首页 > 综合 > 正文

[利用asm代码学习c++语法]--类、private、protected、public、自定义结构体

2013年12月07日 ⁄ 综合 ⁄ 共 5489字 ⁄ 字号 评论关闭

在vs2005下建立vc++的win32 控制台应用程序,设置stdafx.h不必要包含,设置多字符集,设置汇编输出/FAs。代码和asm解析如下:

#include <stdio.h>
struct X
{
 int i,j,k;//0,4,8,12
};
class XXX
{
public:
 int ipub;//0
 X xpub;//4
 int ipub3;//16
protected:
 int ipro;//20
 X xpro;//24
private:
 int ipri;//36
 X xpri;//40
public:
 int ipub2;//52
 X xpub2;//56
public:
 int get_ipri(){return ipri;}
 static void set_ipri(XXX &p, int i){p.ipri = i;}
};
#define PRINTF_OFFSET(TYPE, a) printf("offset of "#TYPE"."#a" = %d/n", &(((TYPE*)0)->a))
int main(int argc, char* argv[])
{
 PRINTF_OFFSET(XXX,ipub);
 PRINTF_OFFSET(XXX,xpub);
 PRINTF_OFFSET(XXX,xpub.i);
 PRINTF_OFFSET(XXX,xpub.k);
 PRINTF_OFFSET(XXX,ipub3);
 PRINTF_OFFSET(XXX,ipub2);
 PRINTF_OFFSET(XXX,xpub2);
 PRINTF_OFFSET(XXX,xpub2.j);
 PRINTF_OFFSET(XXX,xpub2.k);
 XXX t;
 XXX::set_ipri(t, 1);
 printf("t.ipri = %d/n", t.get_ipri());
 *(((int*)(&t))+9) = 110;
 printf("t.ipri = %d/n", t.get_ipri());
 getchar();
 return 0;

_TEXT SEGMENT
_t$ = -72      ; size = 68
_argc$ = 8      ; size = 4
_argv$ = 12      ; size = 4
_main PROC      ; COMDAT

; 27   : {

 push ebp
 mov ebp, esp
 sub esp, 268    ; 0000010cH
 push ebx
 push esi
 push edi
 lea edi, DWORD PTR [ebp-268]
 mov ecx, 67     ; 00000043H
 mov eax, -858993460    ; ccccccccH
 rep stosd

; 28   :  PRINTF_OFFSET(XXX,ipub);

 mov esi, esp
 push 0;XXX中变量的地址在编译期确定
 push OFFSET ??_C@_0BJ@DEEPAIAO@offset?5of?5XXX?4ipub?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 29   :  PRINTF_OFFSET(XXX,xpub);

 mov esi, esp
 push 4;XXX中变量的地址在编译期确定
 push OFFSET ??_C@_0BJ@FLDHBDAF@offset?5of?5XXX?4xpub?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 30   :  PRINTF_OFFSET(XXX,xpub.i);

 mov esi, esp
 push 4;XXX中自定义变量中的变量的地址也在编译期确定
 push OFFSET ??_C@_0BL@NHCPLOO@offset?5of?5XXX?4xpub?4i?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 31   :  PRINTF_OFFSET(XXX,xpub.k);

 mov esi, esp
 push 12     ; 0000000cH;XXX中自定义变量中的变量的地址也在编译期确定
 push OFFSET ??_C@_0BL@EPFHPMJD@offset?5of?5XXX?4xpub?4k?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 32   :  PRINTF_OFFSET(XXX,ipub3);

 mov esi, esp
 push 16     ; 00000010H
 push OFFSET ??_C@_0BK@KPHJBKLN@offset?5of?5XXX?4ipub3?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 33   :  PRINTF_OFFSET(XXX,ipub2);

 mov esi, esp
 push 52     ; 00000034H
 push OFFSET ??_C@_0BK@GDNDBKCD@offset?5of?5XXX?4ipub2?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 34   :  PRINTF_OFFSET(XXX,xpub2);

 mov esi, esp
 push 56     ; 00000038H
 push OFFSET ??_C@_0BK@PEGOLLLA@offset?5of?5XXX?4xpub2?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 35   :  PRINTF_OFFSET(XXX,xpub2.j);

 mov esi, esp
 push 60     ; 0000003cH
 push OFFSET ??_C@_0BM@MCECCCHD@offset?5of?5XXX?4xpub2?4j?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 36   :  PRINTF_OFFSET(XXX,xpub2.k);

 mov esi, esp
 push 64     ; 00000040H;XXX中自定义变量中的变量的地址也在编译期确定
 push OFFSET ??_C@_0BM@OOICCON@offset?5of?5XXX?4xpub2?4k?7?$DN?7?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 37   :  XXX t;
; 38   :  XXX::set_ipri(t, 1);

 push 1
 lea eax, DWORD PTR _t$[ebp];引用参数的传递,实际是地址值
 push eax
 call ?set_ipri@XXX@@SAXAAV1@H@Z  ; XXX::set_ipri
 add esp, 8

; 39   :  printf("t.ipri = %d/n", t.get_ipri());

 lea ecx, DWORD PTR _t$[ebp]
 call ?get_ipri@XXX@@QAEHXZ   ; XXX::get_ipri
 mov esi, esp
 push eax
 push OFFSET ??_C@_0N@CDKCAMPO@t?4ipri?5?$DN?5?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 40   :  *(((int*)(&t))+9) = 110;

 mov DWORD PTR _t$[ebp+36], 110  ; 0000006eH;强行访问private变量也是可行的,说明private修饰符只在编译期有效,实际运行时刻没有所谓的private

; 41   :  printf("t.ipri = %d/n", t.get_ipri());

 lea ecx, DWORD PTR _t$[ebp]
 call ?get_ipri@XXX@@QAEHXZ   ; XXX::get_ipri
 mov esi, esp
 push eax
 push OFFSET ??_C@_0N@CDKCAMPO@t?4ipri?5?$DN?5?$CFd?6?$AA@
 call DWORD PTR __imp__printf
 add esp, 8
 cmp esi, esp
 call __RTC_CheckEsp

; 42   :  getchar();

 mov esi, esp
 call DWORD PTR __imp__getchar
 cmp esi, esp
 call __RTC_CheckEsp

; 43   :  return 0;

 xor eax, eax

; 44   : }

 push edx
 mov ecx, ebp
 push eax
 lea edx, DWORD PTR $LN5@main
 call @_RTC_CheckStackVars@8
 pop eax
 pop edx
 pop edi
 pop esi
 pop ebx
 add esp, 268    ; 0000010cH
 cmp ebp, esp
 call __RTC_CheckEsp
 mov esp, ebp
 pop ebp
 ret 0
 npad 2
$LN5@main:
 DD 1
 DD $LN4@main
$LN4@main:
 DD -72     ; ffffffb8H
 DD 68     ; 00000044H
 DD $LN3@main
$LN3@main:
 DB 116     ; 00000074H
 DB 0
_main ENDP
; Function compile flags: /Odtp /RTCsu /ZI
_TEXT ENDS
; COMDAT ?get_ipri@XXX@@QAEHXZ
_TEXT SEGMENT
_this$ = -8      ; size = 4
?get_ipri@XXX@@QAEHXZ PROC    ; XXX::get_ipri, COMDAT
; _this$ = ecx

; 22   :  int get_ipri(){return ipri;}

 push ebp
 mov ebp, esp
 sub esp, 204    ; 000000ccH
 push ebx
 push esi
 push edi
 push ecx
 lea edi, DWORD PTR [ebp-204]
 mov ecx, 51     ; 00000033H
 mov eax, -858993460    ; ccccccccH
 rep stosd
 pop ecx
 mov DWORD PTR _this$[ebp], ecx
 mov eax, DWORD PTR _this$[ebp]
 mov eax, DWORD PTR [eax+36]
 pop edi
 pop esi
 pop ebx
 mov esp, ebp
 pop ebp
 ret 0
?get_ipri@XXX@@QAEHXZ ENDP    ; XXX::get_ipri
; Function compile flags: /Odtp /RTCsu /ZI
_TEXT ENDS
; COMDAT ?set_ipri@XXX@@SAXAAV1@H@Z
_TEXT SEGMENT
_p$ = 8       ; size = 4
_i$ = 12      ; size = 4
?set_ipri@XXX@@SAXAAV1@H@Z PROC    ; XXX::set_ipri, COMDAT

; 23   :  static void set_ipri(XXX &p, int i){p.ipri = i;}

 push ebp
 mov ebp, esp
 sub esp, 192    ; 000000c0H
 push ebx
 push esi
 push edi
 lea edi, DWORD PTR [ebp-192]
 mov ecx, 48     ; 00000030H
 mov eax, -858993460    ; ccccccccH
 rep stosd
 mov eax, DWORD PTR _p$[ebp]
 mov ecx, DWORD PTR _i$[ebp]
 mov DWORD PTR [eax+36], ecx
 pop edi
 pop esi
 pop ebx
 mov esp, ebp
 pop ebp
 ret 0
?set_ipri@XXX@@SAXAAV1@H@Z ENDP    ; XXX::set_ipri
_TEXT ENDS
END

抱歉!评论已关闭.