Assembly 在C+中创建一个*int+;-MSVC&x27的意义是什么;在将函数返回值分配给全局函数之前,是否额外存储/重新加载函数返回值?
我是汇编代码的初学者。在C++开发时,我注意到一些MSVC生成的汇编代码,我不理解。有关守则是: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
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的情况下构建的,所以当您关闭它时,就会发生这种情况。我投票结束这个问题,因为提出与未优化代码相关的问题是毫无意义的。只是未优化的代码。我猜代码是在关闭优化程序的情况下生成的,所以关闭优化程序时会发生这种情况。我投票结束这个问题,因为问一些与未优化的代码相关的问题是没有意义的,只是未优化的代码。