下面是一段代码,这段代码中有标准未定义的行为。代码如下:
代码语言:javascript复制#include<iostream>
using namespace std;
int main()
{
int j = 0;
for (int i = 0; i < 10; i )
{
j = (j );
}
cout << j << endl;
return 0;
}
编译器版本:
汇编代码:
代码语言:javascript复制 .file "test.cpp"
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.text
.globl main
.type main, @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), �x
leal 1(%rax), �x
movl �x, -8(%rbp)
movl �x, -8(%rbp)
addl $1, -4(%rbp)
jmp .L3
.L2:
movl -8(%rbp), �x
movl �x, %esi
movl $_ZSt4cout, �i
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
movq %rax, %rdi
call _ZNSolsEPFRSoS_E
movl $0, �x
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1021:
.size main, .-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 �i, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L7
cmpl $65535, -8(%rbp)
jne .L7
movl $_ZStL8__ioinit, �i
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, �x
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, �i
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, �i
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汇编以后的汇编代码:
代码语言:javascript复制#include<iostream>
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<char,std::char_traits<char> > (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<char,std::char_traits<char> >::operator<< (03FB09Ch)]
003F1911 cmp edi,esp
003F1913 call __RTC_CheckEsp (03F1230h)
003F1918 mov ecx,eax
003F191A call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (03FB0A0h)]
003F1920 cmp esi,esp
003F1922 call __RTC_CheckEsp (03F1230h)
return 0;
003F1927 xor eax,eax
}