下面是一段代码,这段代码中有标准未定义的行为。代码如下:
#include
using namespace std;
int main()
{
int j = 0;
for (int i = 0; i < 10; i++)
{
j = (j++);
}
cout << j << endl;
return 0;
}
编译器版本:
汇编代码:
.file"test.cpp"
.local_ZStL8__ioinit
.comm_ZStL8__ioinit,1,1
.text
.globlmain
.typemain, @function
main:
.LFB1021:
.cfi_startproc
pushq%rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq%rsp, %rbp
.cfi_def_cfa_register 6
subq$16, %rsp
movl$0, -8(%rbp)
movl$0, -4(%rbp)
.L3:
cmpl$9, -4(%rbp)
jg.L2
movl-8(%rbp), %eax
leal1(%rax), %edx
movl%edx, -8(%rbp)
movl%eax, -8(%rbp)
addl$1, -4(%rbp)
jmp.L3
.L2:
movl-8(%rbp), %eax
movl%eax, %esi
movl$_ZSt4cout, %edi
call_ZNSolsEi
movl$_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
movq%rax, %rdi
call_ZNSolsEPFRSoS_E
movl$0, %eax
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1021:
.sizemain, .-main
.type_Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB1027:
.cfi_startproc
pushq%rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq%rsp, %rbp
.cfi_def_cfa_register 6
subq$16, %rsp
movl%edi, -4(%rbp)
movl%esi, -8(%rbp)
cmpl$1, -4(%rbp)
jne.L7
cmpl$65535, -8(%rbp)
jne.L7
movl$_ZStL8__ioinit, %edi
call_ZNSt8ios_base4InitC1Ev
movl$__dso_handle, %edx
movl$_ZStL8__ioinit, %esi
movl$_ZNSt8ios_base4InitD1Ev, %edi
call__cxa_atexit
.L7:
nop
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1027:
.size_Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.type_GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB1028:
.cfi_startproc
pushq%rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq%rsp, %rbp
.cfi_def_cfa_register 6
movl$65535, %esi
movl$1, %edi
call_Z41__static_initialization_and_destruction_0ii
popq%rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1028:
.size_GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section.init_array,"aw"
.align 8
.quad_GLOBAL__sub_I_main
.hidden__dso_handle
.ident"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section.note.GNU-stack,"",@progbits
下面是VS2019下面使用MSVC汇编以后的汇编代码:
#include
using namespace std;
int main()
{
003F18A1 mov ebp,esp
003F18A3 sub esp,0D8h
003F18A9 push ebx
003F18AA push esi
003F18AB push edi
003F18AC lea edi,[ebp-0D8h]
003F18B2 mov ecx,36h
003F18B7 mov eax,0CCCCCCCCh
003F18BC rep stos dword ptr es:[edi]
003F18BE mov ecx,offset _B1E6438A_源@cpp (03FC026h)
003F18C3 ?? ??
003F18C4 ?? ??
003F18C5 ?? ??
003F18C6 ?? ??
003F18C7 ?? ??
003F18C8 ?? ??
003F18C9 ?? ??
003F18CA ?? ??
003F18CB ?? ??
int j = 0;
003F18CC add byte ptr [eax],al
003F18CE ?? ??
003F18CF ?? ??
003F18D0 ?? ??
003F18D1 ?? ??
003F18D2 ?? ??
for (int i = 0; i < 10; i++)
003F18D3 add byte ptr [eax],al
003F18D5 add bl,ch
003F18D7 or dword ptr [ebx-3F7C13BBh],ecx
003F18DD add dword ptr [ecx+7D83EC45h],ecx
003F18E3 in al,dx
for (int i = 0; i < 10; i++)
003F18E4 or bh,byte ptr [ebp+11h]
{
j = (j++);
003F18E7 mov eax,dword ptr [j]
003F18EA mov dword ptr [j],eax
003F18ED mov ecx,dword ptr [j]
003F18F0 add ecx,1
003F18F3 mov dword ptr [j],ecx
}
003F18F6 jmp main+38h (03F18D8h)
cout << j << endl;
003F18F8 mov esi,esp
003F18FA push offset std::endl > (03F1253h)
003F18FF mov edi,esp
003F1901 mov eax,dword ptr [j]
003F1904 push eax
003F1905 mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (03FB0A8h)]
003F190B call dword ptr [__imp_std::basic_ostream >::operator<< (03FB09Ch)]
003F1911 cmp edi,esp
003F1913 call __RTC_CheckEsp (03F1230h)
003F1918 mov ecx,eax
003F191A call dword ptr [__imp_std::basic_ostream >::operator<< (03FB0A0h)]
003F1920 cmp esi,esp
003F1922 call __RTC_CheckEsp (03F1230h)
return 0;
003F1927 xor eax,eax
}
本文同步分享在 博客“zy010101”(CSDN)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。