从c ++到汇编语言的类

mal*_*luz -3 c++ assembly

我无法理解如何用汇编语言实现类.我检查了使用类的c ++应用程序(visual studio的编译器)的源代码,但它看起来像没有特殊功能的普通代码或其他东西.这个类的构造函数在哪里,它是如何工作的?我猜构造函数的参数是通过堆栈传递的,但是函数unknown_libname_1做了什么?

.text:00261050
.text:00261050 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00261050 _main           proc near               ; CODE XREF: ___tmainCRTStartup+10Ap
.text:00261050
.text:00261050 var_10          = byte ptr -10h
.text:00261050 var_8           = byte ptr -8
.text:00261050 argc            = dword ptr  8
.text:00261050 argv            = dword ptr  0Ch
.text:00261050 envp            = dword ptr  10h
.text:00261050
.text:00261050                 push    ebp
.text:00261051                 mov     ebp, esp
.text:00261053                 sub     esp, 10h
.text:00261056                 push    4
.text:00261058                 push    3
.text:0026105A                 lea     ecx, [ebp+var_8]
.text:0026105D                 call    unknown_libname_1 ; Microsoft VisualC 2-10/net runtime
.text:00261062                 push    6
.text:00261064                 push    5
.text:00261066                 lea     ecx, [ebp+var_10]
.text:00261069                 call    unknown_libname_1 ; Microsoft VisualC 2-10/net runtime
.text:0026106E                 mov     eax, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)
.text:00261073                 push    eax
.text:00261074                 lea     ecx, [ebp+var_8]
.text:00261077                 call    sub_261000
.text:0026107C                 push    eax
.text:0026107D                 push    offset aRectArea ; "rect area: "
.text:00261082                 mov     ecx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
.text:00261088                 push    ecx
.text:00261089                 call    sub_2612D0
.text:0026108E                 add     esp, 8
.text:00261091                 mov     ecx, eax
.text:00261093                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:00261099                 mov     ecx, eax
.text:0026109B                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))
.text:002610A1                 mov     edx, ds:?endl@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z ; std::endl(std::basic_ostream<char,std::char_traits<char>> &)
.text:002610A7                 push    edx
.text:002610A8                 lea     ecx, [ebp+var_10]
.text:002610AB                 call    sub_261000
.text:002610B0                 push    eax
.text:002610B1                 push    offset aRectbArea ; "rectb area: "
.text:002610B6                 mov     eax, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
.text:002610BB                 push    eax
.text:002610BC                 call    sub_2612D0
.text:002610C1                 add     esp, 8
.text:002610C4                 mov     ecx, eax
.text:002610C6                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:002610CC                 mov     ecx, eax
.text:002610CE                 call    ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@P6AAAV01@AAV01@@Z@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(std::basic_ostream<char,std::char_traits<char>> & (*)(std::basic_ostream<char,std::char_traits<char>> &))
.text:002610D4                 xor     eax, eax
.text:002610D6                 mov     esp, ebp
.text:002610D8                 pop     ebp
.text:002610D9                 retn
.text:0026
Run Code Online (Sandbox Code Playgroud)

功能sub_261000:

sub_261000 proc near

var_4= dword ptr -4

push    ebp
mov     ebp, esp
push    ecx
mov     [ebp+var_4], ecx
mov     eax, [ebp+var_4]
mov     ecx, [ebp+var_4]
mov     eax, [eax]
imul    eax, [ecx+4]
mov     esp, ebp
pop     ebp
retn
sub_261000 endp
Run Code Online (Sandbox Code Playgroud)

Jos*_*eld 5

程序集没有任何类的概念.在堆栈上创建类类型的对象时,它只为其所有成员对象腾出空间.成员函数就像普通函数一样,但它也传递一个指针指向这些成员对象的开头,这是this指针.已编译的函数只访问相对于此指针的成员.构造函数只是初始化这些成员对象的另一个函数.

你可以想到这个:

class A {
  private:
    int x;
    short y;
  public:
    A(int arg) : x(arg), y(6) { }
    void print() {
      std::cout << x << ',' << y << std::endl;
    }
};

int main() {
  A a(5);
  a.print()
}
Run Code Online (Sandbox Code Playgroud)

正如变成这样的东西组成了无效的C++:

void A_construct(A* this, int arg) {
  this->x = arg;
  this->y = 6;
}

void A_print(A* this) {
  std::cout << this->x << ',' << this->y << std::endl;
}

int main() {
  int x;
  short y;
  A_construct(this_cast<A*>(&x), 5);
  A_print(this_cast<A*>(&x));
}
Run Code Online (Sandbox Code Playgroud)

化妆的唯一原因this_cast就是允许A*这样我可以继续this->x用来表示"访问那个x对象A".只是为了方便说明.

除了这些运行时细节之外,类所具有的唯一其他影响是它们对您的代码设置了一些编译时限制.例如,您无法编写private从其外部访问类成员的代码.这在组装中没有以任何方式强制执行.