C + + is an object-oriented high-level language, but because it is based on the development of C language, so its intrinsic principle and C language is the same, so to see the C + + program translated into the assembly code is what kind of (in x86 Linux environment, using g++ translation results), using the c++11 new standard, So you can take a look at the c++11 in the Mov semantics exactly how to achieve
First, translation of the 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, cons T 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 (+, +), g); *s = Getsoldior (); Delete g; Delete S;}
Ii. translation of the corresponding ASM assembly files: (only the parts that we understand C + + are retained)
_ZN8POSITIONC2EDDD:; constructor of Positionpushq%rbpmovq%rsp,%RBP; save RBP Movq%rdi, -8 (%RBP); get this pointermovsd%x MM0, -16 (%RBP), Get pxmovsd%xmm1, -24 (%RBP), get py movsd%xmm2, -32 (%RBP), get Pzmovq-8 (%RBP),%rdx movq-16 (%RBP),%raxmov Q%rax, (%RDX), init px movq-8 (%RBP),%rdxmovq-24 (%RBP),%raxmovq%rax, 8 (%RDX), init pymovq-8 (%RBP),%rdxmovq-32 (%RBP),%r Axmovq%rax,%RDX; init pzpopq%rbp; recover rbpret_z8distancerk8positions1_:;d istancepushq%rbpmovq%rsp,%rbpsubq$ %RSP, Extend Stack Movq%rdi, -8 (%RBP), get address of Xmovq%rsi, -16 (%RBP), get address of ymovq-8 (%RBP),%raxmovsd (%r AX),%xmm1; get X.pxmovq-8 (%RBP),%raxmovsd (%rax),%xmm0; get x.pxmulsd%xmm0,%xmm1;%xmm1 = x.px * X.PXMOVQ-8 (%RBP),%rax Movsd8 (%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 addres s 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,%x mm1;%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 r Eturn value of first call to Sqrt to%XMM3SUBSD%XMM0,%xmm3;%xmm3-=%xmm0movapd%xmm3,%xmm0; save%xmm3 to%xmm0 for Pas s 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);p oin ter to virtual function tableof 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 p Oint 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; the pointer to new Guncall_zn3gunc1erks_; Call copy constructor of GUNMOVQ%RBX,%rax; set return value as this pointer to new gunaddq$24,%rs p; 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, (%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 pointer Call_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, + (%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 PO Inter) MOVQ%RBX,%rdi; set this pointer (new gun's this pointer) Call_zn7handgunc1erks_; Call copy constructor of Handgunmov Q%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 Thisc all_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, (%rax), init pos.pymovq16 (%RDX),%RDXMOVQ%RDX,%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;p Ointer to Gun's virtual functions tableaddq$8,%RAXMOVQ (%rax),%rax; secon d function pointer of G ' s virtual tablemovq-24 (%RBP),%RDXMOVQ%RDX,%rdi; set g as ' this ' argumentcall*%rax; call G->co Py_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),%RDX Movq8 (%RDX),%RCXMOVQ%RCX, 8 (%rax);p os.px = S->pos.pxmovq16 (%RDX),%RCXMOVQ%RCX, (%rax);p os.py = s-> Pos.pymovq24 (%RDX),%RDXMOVQ%RDX, (%rax);p Os.pz = S->pos.pz movq-8 (%RBP),%rax; return this. L28:leaveret_zn7soldiord2ev:;d estructor 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 i N Gun's virtual tablemovq (%rax),%raxmovq-8 (%RBP),%rdx movq (%RDX),%RDX; get Gunmovq%rdx,%rdi; set gun as ' this ' argumen Tcall*%rax; call gun ' s destructor. L30:LEAVERETMAIN:PUSHQ%RBPMOVQ%RSP,%rbppushq%r12pushq%rbxsubq$80,%rspmovl%edi, -68 (%RBP) Movq%rsi, -80 (%RBP) movl$ %edi; set Alloc size as Guncall_ZNWM; alloc memory on Heapmovq%rax,%RBX;%rbx are this pointer of new gunmovl$100,%esi; set NBULLETMOVQ%RBX,%rdi; set ' t He ' 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;p Xmovq%rdx, -88 (%RBP) movsd-88 (%RBP),%xmm1;p Ymovq%rax, -88 (%RBP) Movsd-88 (%RBP),%xmm0;p Zmovq%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 GMO Vq%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 GetS Oldiorleaq-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 Soldi Orleaq-48 (%RBP),%rax Movq%rax,%rdicall_zn7soldiord1ev;d elete 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_zn3gun4shoterk8posit Ions2_. 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:;d estructor 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 NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
C + + && compilation