|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
The question is that why ebp-12 is the "this" pointer, how to how?
movl -12(%ebp), %eax //???????????? why ebp-12 is "this" pointer's address, how to know? movl (%eax), %eax addl $4, %eax movl (%eax), %edx movl $5, 4(%esp) movl -12(%ebp), %eax //???????????? why ebp-12 is "this" pointer's address, how to know? movl %eax, (%esp) call *%edx /////////// pMyClass->test1(); eg: #include <iostream> using namespace std; class MyClass { public: MyClass(){ data1 =1; data2 = 2;}; ~MyClass(){}; int data1; int data2; int data3; void print(int data2) { cout << "hello! data1: " << data1 << " data2: " << data2 << endl; } virtual void test1() { data2 = 4; } }; int main() { MyClass * pMyClass; pMyClass = new MyClass; cout << "sizeof(MyClass) = " << sizeof(MyClass) << endl; pMyClass->test1(); pMyClass->print(4); // 1: ÕýÈ·µ÷ÓÃ return 0; } The ASM code of the example is: ################# .globl main .type main, @function main: .LFB1401: leal 4(%esp), %ecx .LCFI19: andl $-16, %esp pushl -4(%ecx) .LCFI20: pushl %ebp .LCFI21: movl %esp, %ebp .LCFI22: pushl %ebx .LCFI23: pushl %ecx .LCFI24: subl $32, %esp .LCFI25: movl $16, (%esp) call _Znwj movl %eax, %ebx movl %ebx, (%esp) call _ZN7MyClassC1Ev movl %ebx, -12(%ebp) movl $.LC2, 4(%esp) movl $_ZSt4cout, (%esp) call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES 5_PKc movl $16, 4(%esp) movl %eax, (%esp) call _ZNSolsEj movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamI T_T0_ES6_, 4(%esp) movl %eax, (%esp) call _ZNSolsEPFRSoS_E movl -12(%ebp), %eax movl (%eax), %eax addl $4, %eax movl (%eax), %edx movl $5, 4(%esp) movl -12(%ebp), %eax //???????????? why ebp-12 is "this" pointer's address, how to know? movl %eax, (%esp) call *%edx /////////// pMyClass->test1(); movl $4, 4(%esp) movl -12(%ebp), %eax movl %eax, (%esp) call _ZN7MyClass5printEi ///////pMyClass- >print(4); movl $0, %eax addl $32, %esp popl %ecx popl %ebx popl %ebp leal -4(%ecx), %esp ret .LFE1401: .size main, .-main .local _ZSt8__ioinit .comm _ZSt8__ioinit,1,1 .weak _ZTV7MyClass .section .gnu.linkonce.r._ZTV7MyClass,"a",@progbits .align 8 .type _ZTV7MyClass, @object .size _ZTV7MyClass, 16 _ZTV7MyClass: .long 0 .long _ZTI7MyClass .long _ZN7MyClass4testEv .long _ZN7MyClass5test1Ei .weak _ZTI7MyClass .section .gnu.linkonce.r._ZTI7MyClass,"a",@progbits .align 4 .type _ZTI7MyClass, @object .size _ZTI7MyClass, 8 _ZTI7MyClass: .long _ZTVN10__cxxabiv117__class_type_infoE+8 .long _ZTS7MyClass .weak _ZTS7MyClass .section .gnu.linkonce.r._ZTS7MyClass,"a",@progbits .type _ZTS7MyClass, @object .size _ZTS7MyClass, 9 _ZTS7MyClass: .string "7MyClass" .section .eh_frame,"a",@progbits . |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Feb 22, 10:13 am, jameschen <wengerm...@gmail.com> wrote:
> The question is that why ebp-12 is the "this" pointer, how to how? > movl -12(%ebp), %eax //???????????? why ebp-12 is > "this" pointer's address, how to know? > movl (%eax), %eax > addl $4, %eax > movl (%eax), %edx > movl $5, 4(%esp) > movl -12(%ebp), %eax //???????????? > why ebp-12 is "this" pointer's address, how to know? > movl %eax, (%esp) > call *%edx /////////// > pMyClass->test1(); > > eg: > #include <iostream> > using namespace std; > > class MyClass > { > public: > MyClass(){ data1 =1; data2 = 2;}; > ~MyClass(){}; > int data1; > int data2; > int data3; > void print(int data2) > { > cout << "hello! data1: " << data1 << " data2: " << data2 << > endl; > } > > virtual void test1() > { > data2 = 4; > } > > }; > > int main() > { > MyClass * pMyClass; > pMyClass = new MyClass; > cout << "sizeof(MyClass) = " << sizeof(MyClass) << endl; > pMyClass->test1(); > pMyClass->print(4); // 1: ÕýÈ·µ÷Óà > > return 0; > > } > > The ASM code of the example is: > ################# > > .globl main > .type main, @function > main: > .LFB1401: > leal 4(%esp), %ecx > .LCFI19: > andl $-16, %esp > pushl -4(%ecx) > .LCFI20: > pushl %ebp > .LCFI21: > movl %esp, %ebp > .LCFI22: > pushl %ebx > .LCFI23: > pushl %ecx > .LCFI24: > subl $32, %esp > .LCFI25: > movl $16, (%esp) > call _Znwj > movl %eax, %ebx > movl %ebx, (%esp) > call _ZN7MyClassC1Ev > movl %ebx, -12(%ebp) > movl $.LC2, 4(%esp) > movl $_ZSt4cout, (%esp) > call > _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES 5_PKc > movl $16, 4(%esp) > movl %eax, (%esp) > call _ZNSolsEj > movl > $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamI T_T0_ES6_, 4(%esp) > movl %eax, (%esp) > call _ZNSolsEPFRSoS_E > movl -12(%ebp), %eax > movl (%eax), %eax > addl $4, %eax > movl (%eax), %edx > movl $5, 4(%esp) > movl -12(%ebp), %eax //???????????? > why ebp-12 is "this" pointer's address, how to know? > movl %eax, (%esp) > call *%edx /////////// > pMyClass->test1(); > movl $4, 4(%esp) > movl -12(%ebp), %eax > movl %eax, (%esp) > call _ZN7MyClass5printEi ///////pMyClass->print(4); > > movl $0, %eax > addl $32, %esp > popl %ecx > popl %ebx > popl %ebp > leal -4(%ecx), %esp > ret > .LFE1401: > .size main, .-main > .local _ZSt8__ioinit > .comm _ZSt8__ioinit,1,1 > .weak _ZTV7MyClass > .section .gnu.linkonce.r._ZTV7MyClass,"a",@progbits > .align 8 > .type _ZTV7MyClass, @object > .size _ZTV7MyClass, 16 > _ZTV7MyClass: > .long 0 > .long _ZTI7MyClass > .long _ZN7MyClass4testEv > .long _ZN7MyClass5test1Ei > .weak _ZTI7MyClass > .section .gnu.linkonce.r._ZTI7MyClass,"a",@progbits > .align 4 > .type _ZTI7MyClass, @object > .size _ZTI7MyClass, 8 > _ZTI7MyClass: > .long _ZTVN10__cxxabiv117__class_type_infoE+8 > .long _ZTS7MyClass > .weak _ZTS7MyClass > .section .gnu.linkonce.r._ZTS7MyClass,"a",@progbits > .type _ZTS7MyClass, @object > .size _ZTS7MyClass, 9 > _ZTS7MyClass: > .string "7MyClass" > .section .eh_frame,"a",@progbits > . I don't know whether I describe the question clear or not£¿ |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
jameschen wrote:
> The question is that why ebp-12 is the "this" pointer, how to how? > movl -12(%ebp), %eax //???????????? why ebp-12 is > "this" pointer's address, how to know? [assembly code redacted] It's implementation specific. You should ask in a newsgroup dedicated to your compiler and platform. Why do you want to know? |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Feb 21, 9:13 pm, jameschen <wengerm...@gmail.com> wrote:
> The question is that why ebp-12 is the "this" pointer, how to how? Like Red said it's implementation-specific. However, many compilers that I've seen implement class member functions by passing a pointer to the instance data ("this") to the member functions as a "hidden" parameter. Similar (sort of) to doing, say, this: struct Something { int data; }; void SomeMemberFunction (Something *s, int param) { s->data = param; } In order to emulate this: class Something { int data; void SomeMemberFunction (int param) { data = param; } }; And so the "this" pointer is passed as a parameter to the member function on the stack; since that info needs to be available inside the member function. Again, that's implementation specific, that's only a general summary, AFAIK there's nothing standardized about that. I wouldn't rely on it being at EBP-12 even with the same compiler. It may also depend on compiler options used, the number of other parameters the function takes, the calling convention, and many other things that you can't rely on. Red Floyd wrote: > Why do you want to know? Yes; unless you are just trying to satisfy your curiosity, if you are considering doing something strange you may want to consider other simpler methods before doing whatever it is you are doing. Jason |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Thank you for your post. jason.cipriani@gmail.com wrote: > On Feb 21, 9:13 pm, jameschen <wengerm...@gmail.com> wrote: > > The question is that why ebp-12 is the "this" pointer, how to how? > > Like Red said it's implementation-specific. However, many compilers > that I've seen implement class member functions by passing a pointer > to the instance data ("this") to the member functions as a "hidden" > parameter. Similar (sort of) to doing, say, this: > > struct Something { > int data; > }; > > void SomeMemberFunction (Something *s, int param) { > s->data = param; > } > > In order to emulate this: > > class Something { > int data; > void SomeMemberFunction (int param) { > data = param; > } > }; > > And so the "this" pointer is passed as a parameter to the member > function on the stack; since that info needs to be available inside > the member function. > > Again, that's implementation specific, that's only a general summary, > AFAIK there's nothing standardized about that. I wouldn't rely on it > being at EBP-12 even with the same compiler. It may also depend on > compiler options used, the number of other parameters the function > takes, the calling convention, and many other things that you can't > rely on. > > Red Floyd wrote: > > Why do you want to know? > > Yes; unless you are just trying to satisfy your curiosity, if you are > considering doing something strange you may want to consider other > simpler methods before doing whatever it is you are doing. > > Jason |
|
![]() |
| Outils de la discussion | |
|
|