c++模板类静态成员变量_UVM世界纵横捭阖之道 - 类静态函数和静态变量

本文围绕UVM工厂机制基石——类静态函数和变量展开。因SV底层不可见,用C++和汇编语言讨论。介绍C++中类静态变量初始化规则,从应用和实现层次分析类静态函数和变量特点,还提及SV在静态变量初始化上与C++的区别,并建议读者在线体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

工厂机制是UVM的关键特性之一,在讨论UVM工厂机制实现之前,我们先讨论工厂机制实现的基石:类静态函数和类静态变量。

由于UVM的实现语言SV(SystemVerilog)的底层实现不可见,我们使用C++和汇编语言进行讨论。接下来从应用层次和实现层次讨论静态变量和静态函数。

talk is cheap,show me the code。首先上一段C++代码。

//filename: hello.cpp
//#include <iostream>
#define MAX_ANIMAL_NUM 20
//#define NULL 0

#if defined(__cplusplus)
    #define NULL 0
#else
    #define NULL ((void *)0)
#endif

class ANIMAL 
{/*{{{*/
    public:
            int age;
    public:
            static int animal_num;
            static ANIMAL *self_id;
            static ANIMAL* animal_list[MAX_ANIMAL_NUM];
            static void record_anmimal(ANIMAL* obj) {/*{{{*/
                if(animal_num==MAX_ANIMAL_NUM) return;
                animal_list[animal_num-1] = obj;
                return;
            }/*}}}*/
            void print_age(){/*{{{*/
                //std::cout << "age is " << age << std::endl;
            }/*}}}*/
            static void print_record(){/*{{{*/
                for(int i=0; i<animal_num; i++){
                    animal_list[i]->print_age();
                }
            }/*}}}*/
            static ANIMAL *get(int age=0)  {/*{{{*/
                if(self_id==NULL) {
                    self_id = new ANIMAL(age);
                    record_anmimal(self_id);
                }
                return self_id;
            }/*}}}*/
            static void print_animal_num() {/*{{{*/
                //std::cout << "animal_num is " << animal_num << std::endl;
            }/*}}}*/
            void set_age(int age) {/*{{{*/
                this->age=age;
            }/*}}}*/
    public:
            ANIMAL() {animal_num++;}
            ~ANIMAL() {animal_num--;}
            ANIMAL(int age) {
                this->age = age; 
                animal_num++;
            }
};/*}}}*/

class DOG : public ANIMAL
{/*{{{*/
    public:
            static DOG *self_id;
            static DOG *get(int age=0) 
            {/*{{{*/
                if(self_id==NULL) {
                    self_id = new DOG(age);
                    //record_anmimal(self_id);
                    record_anmimal((ANIMAL*)self_id);
                }
                return self_id;
            }/*}}}*/
    public:
            DOG() {}
            DOG(int age):ANIMAL(age) {}
            ~DOG() {}
};/*}}}*/

class CAT : public ANIMAL
{/*{{{*/
    public:
            static CAT *self_id;
            static CAT *get(int age=0) 
            {/*{{{*/
                if(self_id==NULL) {
                    self_id = new CAT(age);
                    //record_anmimal(self_id);
                    record_anmimal((ANIMAL*)self_id);
                }
                return self_id;
            }/*}}}*/
    public:
            CAT() {}
            CAT(int age):ANIMAL(age) {}
            ~CAT() {}
};/*}}}*/

int ANIMAL::animal_num  = 0;
ANIMAL* ANIMAL::animal_list[MAX_ANIMAL_NUM]; //NOTE: must declare it
ANIMAL* ANIMAL::self_id = ANIMAL::get(99);
DOG* DOG::self_id       = DOG::get(0x5a);
CAT* CAT::self_id       = CAT::get(0xa5);

const int animal_num_limit_const[3]= {999,0x5a5a,0xa5a5};
int animal_num_limit_var[3]= {999,0x5a5a,0xa5a5};

int bss_buffer[65536];

int main(int argc, char* argv[])
{/*{{{*/

        ANIMAL::print_animal_num();
        ANIMAL *a0 = ANIMAL::get();
        //a0->set_age(2);
        ANIMAL::print_animal_num();
        DOG    *d0 = DOG::get();
        //d0->set_age(3);
        ANIMAL::print_animal_num();
        CAT    *c0 = CAT::get();
        //c0->set_age(4);
        ANIMAL::print_animal_num();
        
        ANIMAL::print_record();
        delete ANIMAL::self_id;
        ANIMAL::print_animal_num();
        delete DOG::self_id;
        ANIMAL::print_animal_num();
        delete CAT::self_id;
        ANIMAL::print_animal_num();
        bss_buffer[0]= 3;
        for(int i=0; i<argc; i++) {
            bss_buffer[i] = i;
            //std::cout<< i << "t:" << bss_buffer[i]<<std::endl;
        }

        return 0;
}/*}}}*/

由于假定了我们的读者具备基本的C++/SV知识,代码的具体内容不再此处赘述。若对本文感兴趣,可花三五小时熟悉下C++的基本知识后再阅读此文。

在C++中,类的静态变量初值若是字面常量可以直接声明并初始化,若初值非字面常量,需要在类外进行声明并初始化赋值(line93~97)。

首先从应用层次看类静态变量和类静态函数。

初值非字面常量的类静态变量是在类中使用static声明、在全局代码区初始化的数据,生命周期和作用范围和全局变量是一致的。

类静态函数在声明时区别于一般类函数的是增加了static关键词。类静态函数属于类,而不属于实例,可通过类符号或实例调用。它不可访问对象/类实例的数据,可以访问类静态变量(其他类的静态变量也可以)和全局变量。

接下来从实现角度看静态函数和静态变量。在msys2终端中使用g++ -masm=intel -S hello.cpp生成汇编语言,可以很容易看出类静态变量和类静态函数在实现上的特点。由于汇编代码由600+行,列在文章最后。

汇编代码较多,添加vim折叠标记后进行折叠,可以得到清晰的代码结构。

b0e0c00ce2b538cb3706122ed3585607.png

类ANIMAL/DOG/CAT的所有函数在;;;function definitions区域定义,包括类静态函数。从底层实现角度看,类静态函数和一般函数是没有什么分别的。

类静态变量则定义/存在于在.bss段,并且编译器生成用于初始化所有类静态变量的初始化函数,这个函数在main函数执行前执行。其中未初始化或初始化值非字面常量的全局变量也在.bss段。

.bss段和.data段(.rdata段是只读的.data段)在内存中的区域都在main执行前初始化,它们的区别在于初始化方式不同。.data段的值在编译时已确定,这些值被编译器写入可执行文件,加载可执行文件时简单的搬运数据以实现.data段内存初始化。而.bss段的值在编译时无法确定或无法简单地确定,因此编译器通常写入可执行文件的是.bss段大小等信息和初始化.bss段的代码。加载可执行文件时申请分配.bss内存,并在main执行前执行.bss段初始化函数,完成.bss段在内存中的初始化工作。

以上是C++的类静态函数和类变量在应用层面和实现层面的简要介绍。SV在静态变量初始化这方便区别于C++的地方在于是SV支持类静态变量在类中直接声明并初始化。SV的静态数据初始化应该是在第一个事件调度time-slot之前完成的。

建议读者在https://www.edaplayground.com/中使用在线的SV编译仿真器irun尝试体会下SV的静态函数和静态变量,尤其是静态变量为关联数组或队列的情况,这是UVM工厂机制的实现基石之一。

【CONTINUED:下一篇文章,我们将聊一聊OOP面向对象程度设计的设计原则和设计模式】

以下是hello.cpp对应的汇编代码,由于语言选择中没有assembly,选择了Clojure,彩色高亮显示有点怪异。

;;;filename: hello.s
	.file	"hello.cpp"
	.intel_syntax noprefix
;;; function definitions
;;;{{{
	.text
;;; ANIMAL::record_anmimal
;;;{{{
	.section	.text$_ZN6ANIMAL14record_anmimalEPS_,"x"
	.linkonce discard
	.globl	_ZN6ANIMAL14record_anmimalEPS_
	.def	_ZN6ANIMAL14record_anmimalEPS_;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMAL14record_anmimalEPS_
_ZN6ANIMAL14record_anmimalEPS_:
.LFB0:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	cmp	eax, 20
	je	.L4
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	sub	eax, 1
	cdqe
	lea	rcx, 0[0+rax*8]
	lea	rdx, _ZN6ANIMAL11animal_listE[rip]
	mov	rax, QWORD PTR 16[rbp]
	mov	QWORD PTR [rcx+rdx], rax
	jmp	.L1
.L4:
	nop
.L1:
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::print_age
;;;{{{
	.section	.text$_ZN6ANIMAL9print_ageEv,"x"
	.linkonce discard
	.align 2
	.globl	_ZN6ANIMAL9print_ageEv
	.def	_ZN6ANIMAL9print_ageEv;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMAL9print_ageEv
_ZN6ANIMAL9print_ageEv:
.LFB1:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	nop
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::print_record
;;;{{{
	.section	.text$_ZN6ANIMAL12print_recordEv,"x"
	.linkonce discard
	.globl	_ZN6ANIMAL12print_recordEv
	.def	_ZN6ANIMAL12print_recordEv;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMAL12print_recordEv
_ZN6ANIMAL12print_recordEv:
.LFB2:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 48
	.seh_stackalloc	48
	.seh_endprologue
	mov	DWORD PTR -4[rbp], 0
.L8:
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	cmp	DWORD PTR -4[rbp], eax
	jge	.L9
	mov	eax, DWORD PTR -4[rbp]
	cdqe
	lea	rdx, 0[0+rax*8]
	lea	rax, _ZN6ANIMAL11animal_listE[rip]
	mov	rax, QWORD PTR [rdx+rax]
	mov	rcx, rax
	call	_ZN6ANIMAL9print_ageEv
	add	DWORD PTR -4[rbp], 1
	jmp	.L8
.L9:
	nop
	add	rsp, 48
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::get
;;;{{{
	.section	.text$_ZN6ANIMAL3getEi,"x"
	.linkonce discard
	.globl	_ZN6ANIMAL3getEi
	.def	_ZN6ANIMAL3getEi;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMAL3getEi
_ZN6ANIMAL3getEi:
.LFB3:
	push	rbp
	.seh_pushreg	rbp
	push	rbx
	.seh_pushreg	rbx
	sub	rsp, 40
	.seh_stackalloc	40
	lea	rbp, 128[rsp]
	.seh_setframe	rbp, 128
	.seh_endprologue
	mov	DWORD PTR -64[rbp], ecx
	mov	rax, QWORD PTR _ZN6ANIMAL7self_idE[rip]
	test	rax, rax
	jne	.L11
	mov	ecx, 4
	call	_Znwm
	mov	rbx, rax
	mov	edx, DWORD PTR -64[rbp]
	mov	rcx, rbx
	call	_ZN6ANIMALC1Ei
	mov	QWORD PTR _ZN6ANIMAL7self_idE[rip], rbx
	mov	rax, QWORD PTR _ZN6ANIMAL7self_idE[rip]
	mov	rcx, rax
	call	_ZN6ANIMAL14record_anmimalEPS_
.L11:
	mov	rax, QWORD PTR _ZN6ANIMAL7self_idE[rip]
	add	rsp, 40
	pop	rbx
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::print_animal_num
;;;{{{
	.section	.text$_ZN6ANIMAL16print_animal_numEv,"x"
	.linkonce discard
	.globl	_ZN6ANIMAL16print_animal_numEv
	.def	_ZN6ANIMAL16print_animal_numEv;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMAL16print_animal_numEv
_ZN6ANIMAL16print_animal_numEv:
.LFB4:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	nop
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::set_age
;;;{{{
	.section	.text$_ZN6ANIMALD2Ev,"x"
	.linkonce discard
	.align 2
	.globl	_ZN6ANIMALD2Ev
	.def	_ZN6ANIMALD2Ev;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMALD2Ev
_ZN6ANIMALD2Ev:
.LFB10:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	sub	eax, 1
	mov	DWORD PTR _ZN6ANIMAL10animal_numE[rip], eax
	nop
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::ANIMAL
;;;{{{
	.section	.text$_ZN6ANIMALD1Ev,"x"
	.linkonce discard
	.align 2
	.globl	_ZN6ANIMALD1Ev
	.def	_ZN6ANIMALD1Ev;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMALD1Ev
_ZN6ANIMALD1Ev:
.LFB11:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	sub	eax, 1
	mov	DWORD PTR _ZN6ANIMAL10animal_numE[rip], eax
	nop
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::~ANIMAL()
;;;{{{
	.section	.text$_ZN6ANIMALC2Ei,"x"
	.linkonce discard
	.align 2
	.globl	_ZN6ANIMALC2Ei
	.def	_ZN6ANIMALC2Ei;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMALC2Ei
_ZN6ANIMALC2Ei:
.LFB13:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	DWORD PTR 24[rbp], edx
	mov	rax, QWORD PTR 16[rbp]
	mov	edx, DWORD PTR 24[rbp]
	mov	DWORD PTR [rax], edx
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	add	eax, 1
	mov	DWORD PTR _ZN6ANIMAL10animal_numE[rip], eax
	nop
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; ANIMAL::ANIMAL(int age) 
;;;{{{
	.section	.text$_ZN6ANIMALC1Ei,"x"
	.linkonce discard
	.align 2
	.globl	_ZN6ANIMALC1Ei
	.def	_ZN6ANIMALC1Ei;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN6ANIMALC1Ei
_ZN6ANIMALC1Ei:
.LFB14:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	DWORD PTR 24[rbp], edx
	mov	rax, QWORD PTR 16[rbp]
	mov	edx, DWORD PTR 24[rbp]
	mov	DWORD PTR [rax], edx
	mov	eax, DWORD PTR _ZN6ANIMAL10animal_numE[rip]
	add	eax, 1
	mov	DWORD PTR _ZN6ANIMAL10animal_numE[rip], eax
	nop
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; DOG::get
;;;{{{
	.section	.text$_ZN3DOG3getEi,"x"
	.linkonce discard
	.globl	_ZN3DOG3getEi
	.def	_ZN3DOG3getEi;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN3DOG3getEi
_ZN3DOG3getEi:
.LFB15:
	push	rbp
	.seh_pushreg	rbp
	push	rbx
	.seh_pushreg	rbx
	sub	rsp, 40
	.seh_stackalloc	40
	lea	rbp, 128[rsp]
	.seh_setframe	rbp, 128
	.seh_endprologue
	mov	DWORD PTR -64[rbp], ecx
	mov	rax, QWORD PTR _ZN3DOG7self_idE[rip]
	test	rax, rax
	jne	.L19
	mov	ecx, 4
	call	_Znwm
	mov	rbx, rax
	mov	edx, DWORD PTR -64[rbp]
	mov	rcx, rbx
	call	_ZN3DOGC1Ei
	mov	QWORD PTR _ZN3DOG7self_idE[rip], rbx
	mov	rax, QWORD PTR _ZN3DOG7self_idE[rip]
	mov	rcx, rax
	call	_ZN6ANIMAL14record_anmimalEPS_
.L19:
	mov	rax, QWORD PTR _ZN3DOG7self_idE[rip]
	add	rsp, 40
	pop	rbx
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; DOG::DOG
;;;{{{
	.section	.text$_ZN3DOGC1Ei,"x"
	.linkonce discard
	.align 2
	.globl	_ZN3DOGC1Ei
	.def	_ZN3DOGC1Ei;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN3DOGC1Ei
_ZN3DOGC1Ei:
.LFB21:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	DWORD PTR 24[rbp], edx
	mov	rax, QWORD PTR 16[rbp]
	mov	edx, DWORD PTR 24[rbp]
	mov	rcx, rax
	call	_ZN6ANIMALC2Ei
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; DOG::~DOG
;;;{{{
	.section	.text$_ZN3DOGD1Ev,"x"
	.linkonce discard
	.align 2
	.globl	_ZN3DOGD1Ev
	.def	_ZN3DOGD1Ev;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN3DOGD1Ev
_ZN3DOGD1Ev:
.LFB24:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	rax, QWORD PTR 16[rbp]
	mov	rcx, rax
	call	_ZN6ANIMALD2Ev
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; CAT::get
;;;{{{
	.section	.text$_ZN3CAT3getEi,"x"
	.linkonce discard
	.globl	_ZN3CAT3getEi
	.def	_ZN3CAT3getEi;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN3CAT3getEi
_ZN3CAT3getEi:
.LFB25:
	push	rbp
	.seh_pushreg	rbp
	push	rbx
	.seh_pushreg	rbx
	sub	rsp, 40
	.seh_stackalloc	40
	lea	rbp, 128[rsp]
	.seh_setframe	rbp, 128
	.seh_endprologue
	mov	DWORD PTR -64[rbp], ecx
	mov	rax, QWORD PTR _ZN3CAT7self_idE[rip]
	test	rax, rax
	jne	.L24
	mov	ecx, 4
	call	_Znwm
	mov	rbx, rax
	mov	edx, DWORD PTR -64[rbp]
	mov	rcx, rbx
	call	_ZN3CATC1Ei
	mov	QWORD PTR _ZN3CAT7self_idE[rip], rbx
	mov	rax, QWORD PTR _ZN3CAT7self_idE[rip]
	mov	rcx, rax
	call	_ZN6ANIMAL14record_anmimalEPS_
.L24:
	mov	rax, QWORD PTR _ZN3CAT7self_idE[rip]
	add	rsp, 40
	pop	rbx
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; CAT::CAT
;;;{{{
	.section	.text$_ZN3CATC1Ei,"x"
	.linkonce discard
	.align 2
	.globl	_ZN3CATC1Ei
	.def	_ZN3CATC1Ei;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN3CATC1Ei
_ZN3CATC1Ei:
.LFB31:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	DWORD PTR 24[rbp], edx
	mov	rax, QWORD PTR 16[rbp]
	mov	edx, DWORD PTR 24[rbp]
	mov	rcx, rax
	call	_ZN6ANIMALC2Ei
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; CAT::~CAT
;;;{{{
	.section	.text$_ZN3CATD1Ev,"x"
	.linkonce discard
	.align 2
	.globl	_ZN3CATD1Ev
	.def	_ZN3CATD1Ev;	.scl	2;	.type	32;	.endef
	.seh_proc	_ZN3CATD1Ev
_ZN3CATD1Ev:
.LFB34:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	mov	QWORD PTR 16[rbp], rcx
	mov	rax, QWORD PTR 16[rbp]
	mov	rcx, rax
	call	_ZN6ANIMALD2Ev
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
;;;}}}

;;;}}}

;;; .bss, here are class static data, ANIMAL::self_id etc.
;;;{{{
	.globl	_ZN6ANIMAL10animal_numE
	.bss
	.align 4
_ZN6ANIMAL10animal_numE:
	.space 4
	.globl	_ZN6ANIMAL11animal_listE
	.align 32
_ZN6ANIMAL11animal_listE:
	.space 160
	.globl	_ZN6ANIMAL7self_idE
	.align 8
_ZN6ANIMAL7self_idE:
	.space 8
	.globl	_ZN3DOG7self_idE
	.align 8
_ZN3DOG7self_idE:
	.space 8
	.globl	_ZN3CAT7self_idE
	.align 8
_ZN3CAT7self_idE:
	.space 8
;;;}}}
;;; .rdata includes global const-declared data, read only, here are animal_num_limit_const
;;;{{{
	.section .rdata,"dr"
	.align 8
_ZL22animal_num_limit_const:
	.long	999
	.long	23130
	.long	42405
;;;}}}
;;; .data includes global const-declared data, read and writable, here are animal_num_limit_var
;;;{{{
	.globl	animal_num_limit_var
	.data
	.align 8
animal_num_limit_var:
	.long	999
	.long	23130
	.long	42405
;;;}}}
;;; .bss, includes global uninit-declared data, here are bss_buffer
;;;{{{ 
	.globl	bss_buffer
	.bss
	.align 32
bss_buffer:
	.space 262144
;;;}}}

;;; main
;;;{{{
	.def	__main;	.scl	2;	.type	32;	.endef
	.text
	.globl	main
	.def	main;	.scl	2;	.type	32;	.endef
	.seh_proc	main
main:
.LFB35:
	push	rbp
	.seh_pushreg	rbp
	push	rbx
	.seh_pushreg	rbx
	sub	rsp, 72
	.seh_stackalloc	72
	lea	rbp, 128[rsp]
	.seh_setframe	rbp, 128
	.seh_endprologue
	mov	DWORD PTR -32[rbp], ecx
	mov	QWORD PTR -24[rbp], rdx
	call	__main
	call	_ZN6ANIMAL16print_animal_numEv
	mov	ecx, 0
	call	_ZN6ANIMAL3getEi
	mov	QWORD PTR -80[rbp], rax
	call	_ZN6ANIMAL16print_animal_numEv
	mov	ecx, 0
	call	_ZN3DOG3getEi
	mov	QWORD PTR -88[rbp], rax
	call	_ZN6ANIMAL16print_animal_numEv
	mov	ecx, 0
	call	_ZN3CAT3getEi
	mov	QWORD PTR -96[rbp], rax
	call	_ZN6ANIMAL16print_animal_numEv
	call	_ZN6ANIMAL12print_recordEv
	mov	rbx, QWORD PTR _ZN6ANIMAL7self_idE[rip]
	test	rbx, rbx
	je	.L29
	mov	rcx, rbx
	call	_ZN6ANIMALD1Ev
	mov	edx, 4
	mov	rcx, rbx
	call	_ZdlPvm
.L29:
	call	_ZN6ANIMAL16print_animal_numEv
	mov	rbx, QWORD PTR _ZN3DOG7self_idE[rip]
	test	rbx, rbx
	je	.L30
	mov	rcx, rbx
	call	_ZN3DOGD1Ev
	mov	edx, 4
	mov	rcx, rbx
	call	_ZdlPvm
.L30:
	call	_ZN6ANIMAL16print_animal_numEv
	mov	rbx, QWORD PTR _ZN3CAT7self_idE[rip]
	test	rbx, rbx
	je	.L31
	mov	rcx, rbx
	call	_ZN3CATD1Ev
	mov	edx, 4
	mov	rcx, rbx
	call	_ZdlPvm
.L31:
	call	_ZN6ANIMAL16print_animal_numEv
	mov	DWORD PTR bss_buffer[rip], 3
	mov	DWORD PTR -68[rbp], 0
.L33:
	mov	eax, DWORD PTR -68[rbp]
	cmp	eax, DWORD PTR -32[rbp]
	jge	.L32
	mov	eax, DWORD PTR -68[rbp]
	cdqe
	lea	rcx, 0[0+rax*4]
	lea	rdx, bss_buffer[rip]
	mov	eax, DWORD PTR -68[rbp]
	mov	DWORD PTR [rcx+rdx], eax
	add	DWORD PTR -68[rbp], 1
	jmp	.L33
.L32:
	mov	eax, 0
	add	rsp, 72
	pop	rbx
	pop	rbp
	ret
	.seh_endproc
;;;}}}

;;; FUNC0: compiler-generted function for .bss init, including bss_buffer and class static data
;;;{{{
	.def	_Z41__static_initialization_and_destruction_0ii;	.scl	3;	.type	32;	.endef
	.seh_proc	_Z41__static_initialization_and_destruction_0ii
_Z41__static_initialization_and_destruction_0ii:
.LFB36:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	mov	DWORD PTR 16[rbp], ecx
	mov	DWORD PTR 24[rbp], edx
	cmp	DWORD PTR 16[rbp], 1
	jne	.L37
	cmp	DWORD PTR 24[rbp], 65535
	jne	.L37
	mov	ecx, 99
	call	_ZN6ANIMAL3getEi
	mov	QWORD PTR _ZN6ANIMAL7self_idE[rip], rax
	mov	ecx, 90
	call	_ZN3DOG3getEi
	mov	QWORD PTR _ZN3DOG7self_idE[rip], rax
	mov	ecx, 165
	call	_ZN3CAT3getEi
	mov	QWORD PTR _ZN3CAT7self_idE[rip], rax
.L37:
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
;;;}}}
;;; FUNC1: wrapper function for FUNC0
;;;{{{
	.def	_GLOBAL__sub_I__ZN6ANIMAL10animal_numE;	.scl	3;	.type	32;	.endef
	.seh_proc	_GLOBAL__sub_I__ZN6ANIMAL10animal_numE
_GLOBAL__sub_I__ZN6ANIMAL10animal_numE:
.LFB37:
	push	rbp
	.seh_pushreg	rbp
	mov	rbp, rsp
	.seh_setframe	rbp, 0
	sub	rsp, 32
	.seh_stackalloc	32
	.seh_endprologue
	mov	edx, 65535
	mov	ecx, 1
	call	_Z41__static_initialization_and_destruction_0ii
	nop
	add	rsp, 32
	pop	rbp
	ret
	.seh_endproc
;;;}}}

;;; section .ctors declares functions exectued BEFORE main, here is FUNC1
;;;{{{
	.section	.ctors,"w"
	.align 8
	.quad	_GLOBAL__sub_I__ZN6ANIMAL10animal_numE
	.ident	"GCC: (GNU) 9.1.0"
	.def	__real__Znwm;	.scl	2;	.type	32;	.endef
	.def	_Znwm;	.scl	2;	.type	32;	.endef
	.def	_ZdlPvm;	.scl	2;	.type	32;	.endef
;;;}}}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值