Assembly 在C+中创建一个*int+;-MSVC&x27的意义是什么;在将函数返回值分配给全局函数之前,是否额外存储/重新加载函数返回值?

Assembly 在C+中创建一个*int+;-MSVC&x27的意义是什么;在将函数返回值分配给全局函数之前,是否额外存储/重新加载函数返回值?,assembly,x86,reverse-engineering,Assembly,X86,Reverse Engineering,我是汇编代码的初学者。在C++开发时,我注意到一些MSVC生成的汇编代码,我不理解。有关守则是: 00DA1965 push 4 // The number of bytes we want 00DA1967 call operator new (0DA1339h) // Call to 'new' to allocate memory 00DA196C add esp,4 // Add the 4 bytes to the stack poin

我是汇编代码的初学者。在C++开发时,我注意到一些MSVC生成的汇编代码,我不理解。有关守则是:

00DA1965  push        4 // The number of bytes we want
00DA1967  call        operator new (0DA1339h) // Call to 'new' to allocate memory
00DA196C  add         esp,4 // Add the 4 bytes to the stack pointer
00DA196F  mov         dword ptr [ebp-0D4h],eax // Move the return address from EAX into a temporary variable?
00DA1975  mov         eax,dword ptr [ebp-0D4h] // Move it back into EAX?
00DA197B  mov         dword ptr [age],eax // And then into my variable?

对应的C++代码:

int *age = new int;
如果我理解正确,我们将EAX中的值移动到EBP-0D4h处的临时变量。在下一个指令中,我们把它移回原来的位置


这有什么意义?(00DA196F和00DA1975)

MSVC的反优化调试构建asm输出通常比gcc或clang的反优化构建更加死板

<>强>没有正确的理由,即使在调试版本中,返回值也会被重载到堆栈中:临时不能通过C++抽象机中的任意名称访问,并且没有调试信息,可以在“代码<新< /代码>结束和代码更新> P<代码> > < < /P>
int*
是一种简单的可复制类型,因此在将返回值复制到本地时没有可运行的复制构造函数。但这大概就是MSVC这么做的原因。


如果将
new
放在全局范围内,gcc不会在函数内部或静态初始值设定项函数中这样做

如果你不想看到愚蠢的死脑筋的asm,那么在编译时启用优化功能,比如MSVC中的
-O2
-Ox
。然后得到预期的静态初始值设定项:

;;; x86 MSVC -O2 output
??__Ep@@YAXXZ PROC                                  ; ??__Ep@@YAXXZ, COMDAT
    push    4
    call    void * operator new(unsigned int)                            ; operator new
    add     esp, 4
    mov     DWORD PTR int * p, eax      ; p
    ret     0
或者对于x86-64

?__Ep@@YAXXZ PROC                                  ; ??__Ep@@YAXXZ, COMDAT
    sub     rsp, 40                             ; 00000028H
    mov     ecx, 4
    call    void * __ptr64 operator new(unsigned __int64)                      ; operator new
    mov     QWORD PTR int * __ptr64 __ptr64 p, rax                ; p
    add     rsp, 40                             ; 00000028H
    ret     0

MSVC的反优化调试构建asm输出通常比gcc或clang的反优化构建更加死板

<>强>没有正确的理由,即使在调试版本中,返回值也会被重载到堆栈中:临时不能通过C++抽象机中的任意名称访问,并且没有调试信息,可以在“代码<新< /代码>结束和代码更新> P<代码> > < < /P>
int*
是一种简单的可复制类型,因此在将返回值复制到本地时没有可运行的复制构造函数。但这大概就是MSVC这么做的原因。


如果将
new
放在全局范围内,gcc不会在函数内部或静态初始值设定项函数中这样做

如果你不想看到愚蠢的死脑筋的asm,那么在编译时启用优化功能,比如MSVC中的
-O2
-Ox
。然后得到预期的静态初始值设定项:

;;; x86 MSVC -O2 output
??__Ep@@YAXXZ PROC                                  ; ??__Ep@@YAXXZ, COMDAT
    push    4
    call    void * operator new(unsigned int)                            ; operator new
    add     esp, 4
    mov     DWORD PTR int * p, eax      ; p
    ret     0
或者对于x86-64

?__Ep@@YAXXZ PROC                                  ; ??__Ep@@YAXXZ, COMDAT
    sub     rsp, 40                             ; 00000028H
    mov     ecx, 4
    call    void * __ptr64 operator new(unsigned __int64)                      ; operator new
    mov     QWORD PTR int * __ptr64 __ptr64 p, rax                ; p
    add     rsp, 40                             ; 00000028H
    ret     0

MSVC正在拆分代码行:

int *age = new int;
分为两个步骤:

                                                ;1st step
        push        4                           ;temp var = new int
        call        operator new
        add         esp,4
        mov         dword ptr [ebp-0D4h],eax
                                                ;2nd step    
        mov         eax,dword ptr [ebp-0D4h]    ;int *age = temp var
        mov         dword ptr [age],eax

MSVC正在拆分代码行:

int *age = new int;
分为两个步骤:

                                                ;1st step
        push        4                           ;temp var = new int
        call        operator new
        add         esp,4
        mov         dword ptr [ebp-0D4h],eax
                                                ;2nd step    
        mov         eax,dword ptr [ebp-0D4h]    ;int *age = temp var
        mov         dword ptr [age],eax

我猜代码是在关闭Optimizer的情况下构建的,所以当您关闭它时,就会发生这种情况。我投票结束这个问题,因为提出与未优化代码相关的问题是毫无意义的。只是未优化的代码。我猜代码是在关闭优化程序的情况下生成的,所以关闭优化程序时会发生这种情况。我投票结束这个问题,因为问一些与未优化的代码相关的问题是没有意义的,只是未优化的代码。