C ++ & amp; assembly, C Language

Source: Internet
Author: User

C ++ & assembly, C Language

C ++ is an object-oriented High-level language, but it is developed based on C language, so its internal principle is exactly the same as that of C language, so let's take a look at what the C ++ program translates into assembly code (in the x86 linux environment, the Translation results are obtained using g ++ ), the new C ++ 11 standard is adopted, so we can take a look at the implementation of mov semantics in C ++ 11.

I. Translated original cpp file:

extern double sqrt(double x);extern double abs(double x);struct Position{public:    Position(double px = 0 , double py = 0 , double pz = 0) : px(px) , py(py) , pz(pz){}    double px , py , pz;};int distance(const Position &x , const Position &y){    return abs(sqrt((x.px * x.px + x.py * x.py + x.pz * x.pz)) - sqrt((y.px * y.px + y.py * y.py + y.pz * y.pz)));}class Gun {public:    Gun(unsigned nbullet = 0) : nbullet(nbullet){}    virtual bool shot(const Position &pfrom , const Position &pto);    void set_bullet(unsigned n)    {        nbullet = n;    }    unsigned get_bullet()const    {        return nbullet;    }    virtual Gun* copy_self()const;    virtual ~Gun(){}private:    unsigned nbullet;};Gun* Gun::copy_self()const{    return new Gun(*this);}bool Gun::shot(const Position &pfrom , const Position &pto){    if(nbullet == 0)        return false;    else        nbullet--;    return true;}class HandGun : public Gun{public:    HandGun(unsigned nbullet = 0 , double dist = 0) : Gun(nbullet) , dist(dist){}    bool shot(const Position &px , const Position &py);    HandGun* copy_self()const;    void set_dist(double d)    {        dist = d;    }    double get_dist()const    {        return dist;    }private:    double dist;};HandGun* HandGun::copy_self()const{    return new HandGun(*this);}bool HandGun::shot(const Position &px , const Position &py){   if(!Gun::shot(px , py))       return false;   return distance(px , py) < dist;}class Soldior{public:   Soldior(const Position &pos , const Gun *g = nullptr) : pos(pos)   {       if(g == nullptr)           gun = nullptr;       else           gun = g->copy_self();   }   Soldior(const Soldior& s)    {      if(s.gun == nullptr)          gun = nullptr;      else          gun = s.gun->copy_self();      pos = s.pos;   }   Soldior(Soldior &&s) noexcept   {       gun = s.gun;       s.gun = nullptr;       pos = s.pos;   }   bool shot(const Position &pt)   {       return gun->shot(pos , pt);   }   Soldior& operator=(const Soldior &s)   {      if(this == &s)          return *this;      if(gun != nullptr)          delete gun;            if(s.gun == nullptr)         gun = nullptr;      else       gun = s.gun->copy_self();      pos = s.pos;      return *this;   }   Soldior& operator=(Soldior &&s)   {      if(this == &s)          return *this;      if(gun != nullptr)          delete gun;      gun = s.gun;      s.gun = nullptr;      pos = s.pos;      return *this;   }    ~Soldior()   {      if(gun != nullptr)         delete gun;   }private:   Gun *gun;   Position pos;}; extern  Soldior getSoldior();int main(int argc , char *argv[]){    Gun *g = new Gun(100);    Soldior *s = new Soldior(Position(20 , 30 , 50) , g);    *s = getSoldior();    delete g;    delete s;}

II. The translated asm Assembly file: (only useful parts of our understanding of C ++ are retained)


_ZN8PositionC2Eddd:  ;constructor of Positionpushq%rbpmovq%rsp, %rbp ;save rbp movq%rdi, -8(%rbp) ;get this pointermovsd%xmm0, -16(%rbp) ;get pxmovsd%xmm1, -24(%rbp) ;get py movsd%xmm2, -32(%rbp) ;get pzmovq-8(%rbp), %rdx movq-16(%rbp), %raxmovq%rax, (%rdx) ;init px movq-8(%rbp), %rdxmovq-24(%rbp), %raxmovq%rax, 8(%rdx) ;init pymovq-8(%rbp), %rdxmovq-32(%rbp), %raxmovq%rax, 16(%rdx) ;init pzpopq%rbp ;recover rbpret_Z8distanceRK8PositionS1_: ;distancepushq%rbpmovq%rsp, %rbpsubq$32, %rsp ;extend stack movq%rdi, -8(%rbp) ;get address of xmovq%rsi, -16(%rbp) ;get address of ymovq-8(%rbp), %raxmovsd(%rax), %xmm1 ;get x.pxmovq-8(%rbp), %raxmovsd(%rax), %xmm0 ;get x.pxmulsd%xmm0, %xmm1 ;%xmm1 = x.px * x.pxmovq-8(%rbp), %raxmovsd8(%rax), %xmm2movq-8(%rbp), %raxmovsd8(%rax), %xmm0mulsd%xmm2, %xmm0 ;%xmm0 = x.py * x.pyaddsd%xmm0, %xmm1 ;%xmm1 += %xmm0movq-8(%rbp), %raxmovsd16(%rax), %xmm2movq-8(%rbp), %raxmovsd16(%rax), %xmm0mulsd%xmm2, %xmm0 ;%xmm0 = x.pz * x.pzaddsd%xmm1, %xmm0 ;%xmm0 += %xmm1call_Z4sqrtd ;call sqrt with argument %xmm0movsd%xmm0, -24(%rbp) ;save return value of sqrtmovq-16(%rbp), %rax ;mov address value of y into %raxmovsd(%rax), %xmm1movq-16(%rbp), %raxmovsd(%rax), %xmm0mulsd%xmm0, %xmm1 ;%xmm1 = y.px * y.pxmovq-16(%rbp), %raxmovsd8(%rax), %xmm2movq-16(%rbp), %raxmovsd8(%rax), %xmm0 mulsd%xmm2, %xmm0 ;%xmm0 = y.py * y.pyaddsd%xmm0, %xmm1 ;%xmm1 += %xmm0movq-16(%rbp), %raxmovsd16(%rax), %xmm2movq-16(%rbp), %raxmovsd16(%rax), %xmm0mulsd%xmm2, %xmm0 ;%xmm0 = y.pz * y.pzaddsd%xmm1, %xmm0 ;%xmm0 += %xmm1call_Z4sqrtd ;call sqrt with argument %xmm0movsd-24(%rbp), %xmm3 ;mov return value of first call to sqrt to %xmm3subsd%xmm0, %xmm3 ;%xmm3 -= %xmm0movapd%xmm3, %xmm0 ;save %xmm3 to %xmm0 for pass to call absd as argumentcall_Z3absd ;call absdcvttsd2si%xmm0, %eax ret_ZN3GunC2Ej: ;constructor of Gunpushq%rbpmovq%rsp, %rbpmovq%rdi, -8(%rbp) ;get this pointermovl%esi, -12(%rbp) ;get nbulletmovq-8(%rbp), %raxmovq$_ZTV3Gun+16, (%rax) ;pointer to virtual function table of class Gunmovq-8(%rbp), %raxmovl-12(%rbp), %edxmovl%edx, 8(%rax) ;init nbulletpopq%rbpret_ZN3GunD2Ev:pushq%rbpmovq%rsp, %rbpsubq$16, %rsp ;extend stack storagemovq%rdi, -8(%rbp) ;get this pointermovq-8(%rbp), %raxmovq$_ZTV3Gun+16, (%rax) ;get pointer to virtual function table of class Gunmovl$0, %eaxtestl%eax, %eaxje.L5movq-8(%rbp), %raxmovq%rax, %rdicall_ZdlPv.L5:leaveret_ZN3GunC2ERKS_: ;copy constructor of Gunpushq%rbpmovq%rsp, %rbpmovq%rdi, -8(%rbp) ;get this pointermovq%rsi, -16(%rbp) ;get address of argument gunmovq-8(%rbp), %rax movq$_ZTV3Gun+16, (%rax) ;set pointer to virtual table with class Gun's virtual table addressmovq-16(%rbp), %rax movl8(%rax), %edx ;%edx point to address of argument gun's nbulletmovq-8(%rbp), %raxmovl%edx, 8(%rax) ;init this->nbulletpopq%rbpret_ZNK3Gun9copy_selfEv: ;Gun::copy_selfpushq%rbpmovq%rsp, %rbppushq%rbxsubq$24, %rsp ;extend stackmovq%rdi, -24(%rbp) ;get this pointermovl$16, %edi ;mov size of Gun to %edicall_Znwm ;alloc memory on heapmovq%rax, %rbx ;this pointer to new gunmovq-24(%rbp), %raxmovq%rax, %rsi ;my own this pointermovq%rbx, %rdi ;this pointer to new guncall_ZN3GunC1ERKS_ ;call copy constructor of Gunmovq%rbx, %rax ;set return value as this pointer to new gunaddq$24, %rsp ;resave stackpopq%rbxpopq%rbpret_ZN3Gun4shotERK8PositionS2_: ;Gun::shotpushq%rbpmovq%rsp, %rbpmovq%rdi, -8(%rbp) ;this pointermovq%rsi, -16(%rbp) ;address of xmovq%rdx, -24(%rbp) ;address of ymovq-8(%rbp), %raxmovl8(%rax), %eax ;address of this->nbullettestl%eax, %eaxjne.L14 ;nbullet != 0movl$0, %eaxjmp.L13.L14:movq-8(%rbp), %raxmovl8(%rax), %eax ;address of this->nbulletleal-1(%rax), %edx movq-8(%rbp), %raxmovl%edx, 8(%rax).L13:popq%rbpret_ZN7HandGunC2Ejd: ;constructor of HandGunpushq%rbpmovq%rsp, %rbpsubq$32, %rspmovq%rdi, -8(%rbp)movl%esi, -12(%rbp)movsd%xmm0, -24(%rbp)movq-8(%rbp), %raxmovl-12(%rbp), %edxmovl%edx, %esi ;set nbulletmovq%rax, %rdi ;set this pointercall_ZN3GunC2Ej ;call constructor of Gunmovq-8(%rbp), %raxmovq$_ZTV7HandGun+16, (%rax) ;set virtual function pointermovq-8(%rbp), %rdxmovq-24(%rbp), %raxmovq%rax, 16(%rdx) ;init distleaveret_ZN7HandGunC2ERKS_: ;copy constructor of HandGunpushq%rbpmovq%rsp, %rbpsubq$16, %rspmovq%rdi, -8(%rbp)movq%rsi, -16(%rbp)movq-16(%rbp), %rdxmovq-8(%rbp), %raxmovq%rdx, %rsi ;set arg gun's this pointermovq%rax, %rdi ;set my own this pointercall_ZN3GunC2ERKS_ ;call Gun's copy constructormovq-8(%rbp), %raxmovq$_ZTV7HandGun+16, (%rax) ;set virtual function pointermovq-16(%rbp), %raxmovq16(%rax), %rax ;get arg gun's distmovq-8(%rbp), %rdxmovq%rax, 16(%rdx) ;init distleaveret_ZNK7HandGun9copy_selfEv: ;HandGun::copy_selfpushq%rbpmovq%rsp, %rbppushq%rbxsubq$24, %rspmovq%rdi, -24(%rbp) ;my own this pointermovl$24, %edicall_Znwmmovq%rax, %rbx ;get address of new gunmovq-24(%rbp), %raxmovq%rax, %rsi ;set arg gun's address (my own this pointer)movq%rbx, %rdi ;set this pointer (new gun's this pointer)call_ZN7HandGunC1ERKS_ ;call copy constructor of HandGunmovq%rbx, %rax ;set new this pointer as return valueaddq$24, %rsp ;resave stackpopq%rbxpopq%rbpret_ZN7HandGun4shotERK8PositionS2_: ;HandGun::shotpushq%rbpmovq%rsp, %rbpsubq$32, %rspmovq%rdi, -8(%rbp)movq%rsi, -16(%rbp)movq%rdx, -24(%rbp)movq-8(%rbp), %rax ;thismovq-24(%rbp), %rdx ;addr of xmovq-16(%rbp), %rcx ;addr of ymovq%rcx, %rsi ;set ymovq%rax, %rdi ;set thiscall_ZN3Gun4shotERK8PositionS2_ ;call Gun::shotxorl$1, %eax ;check return valuetestb%al, %alje.L21 ;truemovl$0, %eaxjmp.L22.L21:movq-24(%rbp), %rdxmovq-16(%rbp), %raxmovq%rdx, %rsi ;set xmovq%rax, %rdi ;set ycall_Z8distanceRK8PositionS1_ ;call distancecvtsi2sd%eax, %xmm0 movq-8(%rbp), %raxmovsd16(%rax), %xmm1 ucomisd%xmm0, %xmm1seta%al.L22:leaveret_ZN7SoldiorC2ERK8PositionPK3Gun: ;constructor of Soldiorpushq%rbpmovq%rsp, %rbpsubq$32, %rspmovq%rdi, -8(%rbp)movq%rsi, -16(%rbp)movq%rdx, -24(%rbp)movq-8(%rbp), %rax ;thismovq-16(%rbp), %rdx ;addr of posmovq(%rdx), %rcxmovq%rcx, 8(%rax) ;init pos.pxmovq8(%rdx), %rcxmovq%rcx, 16(%rax) ;init pos.pymovq16(%rdx), %rdxmovq%rdx, 24(%rax) ;init pos.pzcmpq$0, -24(%rbp) jne.L24 ;g != nullptrmovq-8(%rbp), %raxmovq$0, (%rax) ;init gun as nullptrjmp.L23.L24:movq-24(%rbp), %rax ;thismovq(%rax), %rax ;pointer to Gun's virtual functions tableaddq$8, %raxmovq(%rax), %rax ;second function pointer of g's virtual tablemovq-24(%rbp), %rdxmovq%rdx, %rdi ;set g as 'this' argumentcall*%rax ;call g->copy_selfmovq-8(%rbp), %rdxmovq%rax, (%rdx) ;gun = g.L23:leaveret_ZN7SoldioraSEOS_: ;mov assignmentpushq%rbpmovq%rsp, %rbpsubq$16, %rspmovq%rdi, -8(%rbp)movq%rsi, -16(%rbp)movq-8(%rbp), %raxcmpq-16(%rbp), %rax jne.L27 ;if(this != &s)movq-8(%rbp), %raxjmp.L28.L27:movq-8(%rbp), %rax movq(%rax), %raxtestq%rax, %raxje.L29 ;this->gun == nullptrmovq-8(%rbp), %raxmovq(%rax), %raxtestq%rax, %raxje.L29movq-8(%rbp), %raxmovq(%rax), %raxmovq(%rax), %raxaddq$24, %raxmovq(%rax), %raxmovq-8(%rbp), %rdxmovq(%rdx), %rdxmovq%rdx, %rdicall*%rax ;call gun's destructor.L29:movq-16(%rbp), %raxmovq(%rax), %rdxmovq-8(%rbp), %raxmovq%rdx, (%rax) ;gun = s->gunmovq-16(%rbp), %raxmovq$0, (%rax) ;s->gun = nullptrmovq-8(%rbp), %raxmovq-16(%rbp), %rdxmovq8(%rdx), %rcxmovq%rcx, 8(%rax) ;pos.px = s->pos.pxmovq16(%rdx), %rcxmovq%rcx, 16(%rax) ;pos.py = s->pos.pymovq24(%rdx), %rdxmovq%rdx, 24(%rax) ;pos.pz = s->pos.pz movq-8(%rbp), %rax ;return this.L28:leaveret_ZN7SoldiorD2Ev: ;destructor of Soldiorpushq%rbpmovq%rsp, %rbp subq$16, %rspmovq%rdi, -8(%rbp)movq-8(%rbp), %raxmovq(%rax), %rax ;%rax = guntestq%rax, %rax je.L30 ;gun == nullptrmovq-8(%rbp), %raxmovq(%rax), %raxtestq%rax, %rax je.L30 ;gun == nullptrmovq-8(%rbp), %raxmovq(%rax), %raxmovq(%rax), %rax ;gun->vptraddq$24, %rax ;third function pointer in gun's virtual tablemovq(%rax), %raxmovq-8(%rbp), %rdx movq(%rdx), %rdx ;get gunmovq%rdx, %rdi ;set gun as 'this' argumentcall*%rax ;call gun's destructor.L30:leaveretmain:pushq%rbpmovq%rsp, %rbppushq%r12pushq%rbxsubq$80, %rspmovl%edi, -68(%rbp)movq%rsi, -80(%rbp)movl$16, %edi ;set alloc size as Guncall_Znwm ;alloc memory on heapmovq%rax, %rbx ;%rbx is this pointer of new gunmovl$100, %esi ;set nbulletmovq%rbx, %rdi ;set 'this' argcall_ZN3GunC1Ej ;call constructor of Gunmovq%rbx, -64(%rbp) ;save %rbxmovabsq$4632233691727265792, %rcx ;constexpr accessed as static addressmovabsq$4629137466983448576, %rdxmovabsq$4626322717216342016, %raxleaq-48(%rbp), %rsimovq%rcx, -88(%rbp)movsd-88(%rbp), %xmm2 ;pxmovq%rdx, -88(%rbp)movsd-88(%rbp), %xmm1 ;pymovq%rax, -88(%rbp)movsd-88(%rbp), %xmm0 ;pzmovq%rsi, %rdi ;set 'this' argcall_ZN8PositionC1Eddd ;call constructor of Positionleaq-48(%rbp), %r12 movl$32, %edi ;set alloc size as Soldior's sizecall_Znwmmovq%rax, %rbx ;smovq-64(%rbp), %raxmovq%rax, %rdx ;set gmovq%r12, %rsi ;set posmovq%rbx, %rdi ;set 'this' argcall_ZN7SoldiorC1ERK8PositionPK3Gun ;call Soldior's constructormovq%rbx, -56(%rbp) ;save %rbxleaq-48(%rbp), %raxmovq%rax, %rdi ;set return addr of next functioncall_Z10getSoldiorv ;call getSoldiorleaq-48(%rbp), %rdx ;get return valmovq-56(%rbp), %rax  ;get smovq%rdx, %rsi ;set 's' argmovq%rax, %rdi ;set 'this' argcall_ZN7SoldioraSEOS_ ;call mov assignment of Soldiorleaq-48(%rbp), %rax movq%rax, %rdicall_ZN7SoldiorD1Ev ;delete return val of getSoldiormovl$0, %eaxjmp.L38.L37:movq%rax, %r12movq%rbx, %rdicall_ZdlPvmovq%r12, %raxmovq%rax, %rdicall_Unwind_Resume.L38:addq$80, %rsppopq%rbxpopq%r12popq%rbpret_ZTV3Gun: ;Gun's virtual functions table.quad0.quad_ZTI3Gun ;some information of this table , we can ignore.quad_ZN3Gun4shotERK8PositionS2_ .quad_ZNK3Gun9copy_selfEv.quad_ZN3GunD1Ev.quad_ZN3GunD0Ev.weak_ZTI7HandGun.section.rodata._ZTI7HandGun,"aG",@progbits,_ZTI7HandGun,comdat.align 16.type_ZTI7HandGun, @object.size_ZTI7HandGun, 24_ZTV7HandGun: ;virtual function table of HandGun.quad0.quad_ZTI7HandGun.quad_ZN7HandGun4shotERK8PositionS2_.quad_ZNK7HandGun9copy_selfEv.quad_ZN7HandGunD1Ev.quad_ZN7HandGunD0Ev.section.text._ZN7HandGunD2Ev,"axG",@progbits,_ZN7HandGunD5Ev,comdat.align 2.weak_ZN7HandGunD2Ev.type_ZN7HandGunD2Ev, @function_ZN7HandGunD2Ev: ;destructor of HandGunpushq%rbpmovq%rsp, %rbpsubq$16, %rspmovq%rdi, -8(%rbp)movq-8(%rbp), %raxmovq$_ZTV7HandGun+16, (%rax) ;set vptrmovq-8(%rbp), %raxmovq%rax, %rdicall_ZN3GunD2Ev ;call Gun's destructormovl$0, %eaxtestl%eax, %eaxje.L39movq-8(%rbp), %raxmovq%rax, %rdicall_ZdlPv.L39:leaveret




Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.