主頁 > 後端開發 > 函式執行順序

函式執行順序

2023-01-13 06:23:58 後端開發

C++物件構造和析構

//遺留的問題:C++中建構式和解構式的執行順序到底是怎么樣的呢?
class Object
{
private:
    int val;
public:
    Object(int x)
    {
        val = x;
        cout << "create :" << val << endl;
    }    
};
Object o1(1);

int main()
{
    Object o2(2);
}

Object o3(3);

代碼在Linux64平臺編譯運行,objdump -d 生成反匯編代碼

匯編代碼如下:

反匯編代碼
Object:     檔案格式 elf64-x86-64

Disassembly of section .init:

0000000000001000 <_init>:
    1000:       f3 0f 1e fa             endbr64 
    1004:       48 83 ec 08             sub    $0x8,%rsp
    1008:       48 8b 05 d9 2f 00 00    mov    0x2fd9(%rip),%rax        # 3fe8 <__gmon_start__>
    100f:       48 85 c0                test   %rax,%rax
    1012:       74 02                   je     1016 <_init+0x16>
    1014:       ff d0                   callq  *%rax
    1016:       48 83 c4 08             add    $0x8,%rsp
    101a:       c3                      retq   

Disassembly of section .plt:

0000000000001020 <.plt>:
    1020:       ff 35 62 2f 00 00       pushq  0x2f62(%rip)        # 3f88 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:       f2 ff 25 63 2f 00 00    bnd jmpq *0x2f63(%rip)        # 3f90 <_GLOBAL_OFFSET_TABLE_+0x10>
    102d:       0f 1f 00                nopl   (%rax)
    1030:       f3 0f 1e fa             endbr64 
    1034:       68 00 00 00 00          pushq  $0x0
    1039:       f2 e9 e1 ff ff ff       bnd jmpq 1020 <.plt>
    103f:       90                      nop
    1040:       f3 0f 1e fa             endbr64 
    1044:       68 01 00 00 00          pushq  $0x1
    1049:       f2 e9 d1 ff ff ff       bnd jmpq 1020 <.plt>
    104f:       90                      nop
    1050:       f3 0f 1e fa             endbr64 
    1054:       68 02 00 00 00          pushq  $0x2
    1059:       f2 e9 c1 ff ff ff       bnd jmpq 1020 <.plt>
    105f:       90                      nop
    1060:       f3 0f 1e fa             endbr64 
    1064:       68 03 00 00 00          pushq  $0x3
    1069:       f2 e9 b1 ff ff ff       bnd jmpq 1020 <.plt>
    106f:       90                      nop
    1070:       f3 0f 1e fa             endbr64 
    1074:       68 04 00 00 00          pushq  $0x4
    1079:       f2 e9 a1 ff ff ff       bnd jmpq 1020 <.plt>
    107f:       90                      nop
    1080:       f3 0f 1e fa             endbr64 
    1084:       68 05 00 00 00          pushq  $0x5
    1089:       f2 e9 91 ff ff ff       bnd jmpq 1020 <.plt>
    108f:       90                      nop

Disassembly of section .plt.got:

0000000000001090 <__cxa_finalize@plt>:
    1090:       f3 0f 1e fa             endbr64 
    1094:       f2 ff 25 2d 2f 00 00    bnd jmpq *0x2f2d(%rip)        # 3fc8 <__cxa_finalize@GLIBC_2.2.5>
    109b:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

Disassembly of section .plt.sec:

00000000000010a0 <__cxa_atexit@plt>:
    10a0:       f3 0f 1e fa             endbr64 
    10a4:       f2 ff 25 ed 2e 00 00    bnd jmpq *0x2eed(%rip)        # 3f98 <__cxa_atexit@GLIBC_2.2.5>
    10ab:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

00000000000010b0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>:
    10b0:       f3 0f 1e fa             endbr64 
    10b4:       f2 ff 25 e5 2e 00 00    bnd jmpq *0x2ee5(%rip)        # 3fa0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@GLIBCXX_3.4>
    10bb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

00000000000010c0 <_ZNSolsEPFRSoS_E@plt>:
    10c0:       f3 0f 1e fa             endbr64 
    10c4:       f2 ff 25 dd 2e 00 00    bnd jmpq *0x2edd(%rip)        # 3fa8 <_ZNSolsEPFRSoS_E@GLIBCXX_3.4>
    10cb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

00000000000010d0 <__stack_chk_fail@plt>:
    10d0:       f3 0f 1e fa             endbr64 
    10d4:       f2 ff 25 d5 2e 00 00    bnd jmpq *0x2ed5(%rip)        # 3fb0 <__stack_chk_fail@GLIBC_2.4>
    10db:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

00000000000010e0 <_ZNSt8ios_base4InitC1Ev@plt>:
    10e0:       f3 0f 1e fa             endbr64 
    10e4:       f2 ff 25 cd 2e 00 00    bnd jmpq *0x2ecd(%rip)        # 3fb8 <_ZNSt8ios_base4InitC1Ev@GLIBCXX_3.4>
    10eb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

00000000000010f0 <_ZNSolsEi@plt>:
    10f0:       f3 0f 1e fa             endbr64 
    10f4:       f2 ff 25 c5 2e 00 00    bnd jmpq *0x2ec5(%rip)        # 3fc0 <_ZNSolsEi@GLIBCXX_3.4>
    10fb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

Disassembly of section .text:

0000000000001100 <_start>:
    1100:       f3 0f 1e fa             endbr64 
    1104:       31 ed                   xor    %ebp,%ebp
    1106:       49 89 d1                mov    %rdx,%r9
    1109:       5e                      pop    %rsi
    110a:       48 89 e2                mov    %rsp,%rdx
    110d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    1111:       50                      push   %rax
    1112:       54                      push   %rsp
    1113:       4c 8d 05 f6 02 00 00    lea    0x2f6(%rip),%r8        # 1410 <__libc_csu_fini>
    111a:       48 8d 0d 7f 02 00 00    lea    0x27f(%rip),%rcx        # 13a0 <__libc_csu_init>
    1121:       48 8d 3d c1 00 00 00    lea    0xc1(%rip),%rdi        # 11e9 <main>
    1128:       ff 15 b2 2e 00 00       callq  *0x2eb2(%rip)        # 3fe0 <__libc_start_main@GLIBC_2.2.5>
    112e:       f4                      hlt    
    112f:       90                      nop

0000000000001130 <deregister_tm_clones>:
    1130:       48 8d 3d e1 2e 00 00    lea    0x2ee1(%rip),%rdi        # 4018 <__TMC_END__>
    1137:       48 8d 05 da 2e 00 00    lea    0x2eda(%rip),%rax        # 4018 <__TMC_END__>
    113e:       48 39 f8                cmp    %rdi,%rax
    1141:       74 15                   je     1158 <deregister_tm_clones+0x28>
    1143:       48 8b 05 8e 2e 00 00    mov    0x2e8e(%rip),%rax        # 3fd8 <_ITM_deregisterTMCloneTable>
    114a:       48 85 c0                test   %rax,%rax
    114d:       74 09                   je     1158 <deregister_tm_clones+0x28>
    114f:       ff e0                   jmpq   *%rax
    1151:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    1158:       c3                      retq   
    1159:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

0000000000001160 <register_tm_clones>:
    1160:       48 8d 3d b1 2e 00 00    lea    0x2eb1(%rip),%rdi        # 4018 <__TMC_END__>
    1167:       48 8d 35 aa 2e 00 00    lea    0x2eaa(%rip),%rsi        # 4018 <__TMC_END__>
    116e:       48 29 fe                sub    %rdi,%rsi
    1171:       48 89 f0                mov    %rsi,%rax
    1174:       48 c1 ee 3f             shr    $0x3f,%rsi
    1178:       48 c1 f8 03             sar    $0x3,%rax
    117c:       48 01 c6                add    %rax,%rsi
    117f:       48 d1 fe                sar    %rsi
    1182:       74 14                   je     1198 <register_tm_clones+0x38>
    1184:       48 8b 05 65 2e 00 00    mov    0x2e65(%rip),%rax        # 3ff0 <_ITM_registerTMCloneTable>
    118b:       48 85 c0                test   %rax,%rax
    118e:       74 08                   je     1198 <register_tm_clones+0x38>
    1190:       ff e0                   jmpq   *%rax
    1192:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
    1198:       c3                      retq   
    1199:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000000011a0 <__do_global_dtors_aux>:
    11a0:       f3 0f 1e fa             endbr64 
    11a4:       80 3d a5 2f 00 00 00    cmpb   $0x0,0x2fa5(%rip)        # 4150 <completed.8060>
    11ab:       75 2b                   jne    11d8 <__do_global_dtors_aux+0x38>
    11ad:       55                      push   %rbp
    11ae:       48 83 3d 12 2e 00 00    cmpq   $0x0,0x2e12(%rip)        # 3fc8 <__cxa_finalize@GLIBC_2.2.5>
    11b5:       00 
    11b6:       48 89 e5                mov    %rsp,%rbp
    11b9:       74 0c                   je     11c7 <__do_global_dtors_aux+0x27>
    11bb:       48 8b 3d 46 2e 00 00    mov    0x2e46(%rip),%rdi        # 4008 <__dso_handle>
    11c2:       e8 c9 fe ff ff          callq  1090 <__cxa_finalize@plt>
    11c7:       e8 64 ff ff ff          callq  1130 <deregister_tm_clones>
    11cc:       c6 05 7d 2f 00 00 01    movb   $0x1,0x2f7d(%rip)        # 4150 <completed.8060>
    11d3:       5d                      pop    %rbp
    11d4:       c3                      retq   
    11d5:       0f 1f 00                nopl   (%rax)
    11d8:       c3                      retq   
    11d9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

00000000000011e0 <frame_dummy>:
    11e0:       f3 0f 1e fa             endbr64 
    11e4:       e9 77 ff ff ff          jmpq   1160 <register_tm_clones>

00000000000011e9 <main>:
    11e9:       f3 0f 1e fa             endbr64 
    11ed:       55                      push   %rbp
    11ee:       48 89 e5                mov    %rsp,%rbp
    11f1:       48 83 ec 10             sub    $0x10,%rsp
    11f5:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
    11fc:       00 00 
    11fe:       48 89 45 f8             mov    %rax,-0x8(%rbp)
    1202:       31 c0                   xor    %eax,%eax
    1204:       48 8d 45 f4             lea    -0xc(%rbp),%rax
    1208:       be 02 00 00 00          mov    $0x2,%esi
    120d:       48 89 c7                mov    %rax,%rdi
    1210:       e8 e7 00 00 00          callq  12fc <_ZN6ObjectC1Ei>
    1215:       48 8d 45 f4             lea    -0xc(%rbp),%rax
    1219:       48 89 c7                mov    %rax,%rdi
    121c:       e8 35 01 00 00          callq  1356 <_ZN6ObjectD1Ev>
    1221:       b8 00 00 00 00          mov    $0x0,%eax
    1226:       48 8b 55 f8             mov    -0x8(%rbp),%rdx
    122a:       64 48 33 14 25 28 00    xor    %fs:0x28,%rdx
    1231:       00 00 
    1233:       74 05                   je     123a <main+0x51>
    1235:       e8 96 fe ff ff          callq  10d0 <__stack_chk_fail@plt>
    123a:       c9                      leaveq 
    123b:       c3                      retq   

000000000000123c <_Z41__static_initialization_and_destruction_0ii>:
    123c:       f3 0f 1e fa             endbr64 
    1240:       55                      push   %rbp
    1241:       48 89 e5                mov    %rsp,%rbp
    1244:       48 83 ec 10             sub    $0x10,%rsp
    1248:       89 7d fc                mov    %edi,-0x4(%rbp)
    124b:       89 75 f8                mov    %esi,-0x8(%rbp)
    124e:       83 7d fc 01             cmpl   $0x1,-0x4(%rbp)
    1252:       0f 85 88 00 00 00       jne    12e0 <_Z41__static_initialization_and_destruction_0ii+0xa4>
    1258:       81 7d f8 ff ff 00 00    cmpl   $0xffff,-0x8(%rbp)
    125f:       75 7f                   jne    12e0 <_Z41__static_initialization_and_destruction_0ii+0xa4>
    1261:       48 8d 3d f4 2e 00 00    lea    0x2ef4(%rip),%rdi        # 415c <_ZStL8__ioinit>
    1268:       e8 73 fe ff ff          callq  10e0 <_ZNSt8ios_base4InitC1Ev@plt>
    126d:       48 8d 15 94 2d 00 00    lea    0x2d94(%rip),%rdx        # 4008 <__dso_handle>
    1274:       48 8d 35 e1 2e 00 00    lea    0x2ee1(%rip),%rsi        # 415c <_ZStL8__ioinit>
    127b:       48 8b 05 76 2d 00 00    mov    0x2d76(%rip),%rax        # 3ff8 <_ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4>
    1282:       48 89 c7                mov    %rax,%rdi
    1285:       e8 16 fe ff ff          callq  10a0 <__cxa_atexit@plt>
    128a:       be 01 00 00 00          mov    $0x1,%esi
    128f:       48 8d 3d be 2e 00 00    lea    0x2ebe(%rip),%rdi        # 4154 <o1>
    1296:       e8 61 00 00 00          callq  12fc <_ZN6ObjectC1Ei>
    129b:       48 8d 15 66 2d 00 00    lea    0x2d66(%rip),%rdx        # 4008 <__dso_handle>
    12a2:       48 8d 35 ab 2e 00 00    lea    0x2eab(%rip),%rsi        # 4154 <o1>
    12a9:       48 8d 3d a6 00 00 00    lea    0xa6(%rip),%rdi        # 1356 <_ZN6ObjectD1Ev>
    12b0:       e8 eb fd ff ff          callq  10a0 <__cxa_atexit@plt>
    12b5:       be 03 00 00 00          mov    $0x3,%esi
    12ba:       48 8d 3d 97 2e 00 00    lea    0x2e97(%rip),%rdi        # 4158 <o3>
    12c1:       e8 36 00 00 00          callq  12fc <_ZN6ObjectC1Ei>
    12c6:       48 8d 15 3b 2d 00 00    lea    0x2d3b(%rip),%rdx        # 4008 <__dso_handle>
    12cd:       48 8d 35 84 2e 00 00    lea    0x2e84(%rip),%rsi        # 4158 <o3>
    12d4:       48 8d 3d 7b 00 00 00    lea    0x7b(%rip),%rdi        # 1356 <_ZN6ObjectD1Ev>
    12db:       e8 c0 fd ff ff          callq  10a0 <__cxa_atexit@plt>
    12e0:       90                      nop
    12e1:       c9                      leaveq 
    12e2:       c3                      retq   

00000000000012e3 <_GLOBAL__sub_I_o1>:
    12e3:       f3 0f 1e fa             endbr64 
    12e7:       55                      push   %rbp
    12e8:       48 89 e5                mov    %rsp,%rbp
    12eb:       be ff ff 00 00          mov    $0xffff,%esi
    12f0:       bf 01 00 00 00          mov    $0x1,%edi
    12f5:       e8 42 ff ff ff          callq  123c <_Z41__static_initialization_and_destruction_0ii>
    12fa:       5d                      pop    %rbp
    12fb:       c3                      retq   

00000000000012fc <_ZN6ObjectC1Ei>:
    12fc:       f3 0f 1e fa             endbr64 
    1300:       55                      push   %rbp
    1301:       48 89 e5                mov    %rsp,%rbp
    1304:       48 83 ec 10             sub    $0x10,%rsp
    1308:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
    130c:       89 75 f4                mov    %esi,-0xc(%rbp)
    130f:       48 8b 45 f8             mov    -0x8(%rbp),%rax
    1313:       8b 55 f4                mov    -0xc(%rbp),%edx
    1316:       89 10                   mov    %edx,(%rax)
    1318:       48 8d 35 e6 0c 00 00    lea    0xce6(%rip),%rsi        # 2005 <_ZStL19piecewise_construct+0x1>
    131f:       48 8d 3d 1a 2d 00 00    lea    0x2d1a(%rip),%rdi        # 4040 <_ZSt4cout@@GLIBCXX_3.4>
    1326:       e8 85 fd ff ff          callq  10b0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
    132b:       48 89 c2                mov    %rax,%rdx
    132e:       48 8b 45 f8             mov    -0x8(%rbp),%rax
    1332:       8b 00                   mov    (%rax),%eax
    1334:       89 c6                   mov    %eax,%esi
    1336:       48 89 d7                mov    %rdx,%rdi
    1339:       e8 b2 fd ff ff          callq  10f0 <_ZNSolsEi@plt>
    133e:       48 89 c2                mov    %rax,%rdx
    1341:       48 8b 05 88 2c 00 00    mov    0x2c88(%rip),%rax        # 3fd0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
    1348:       48 89 c6                mov    %rax,%rsi
    134b:       48 89 d7                mov    %rdx,%rdi
    134e:       e8 6d fd ff ff          callq  10c0 <_ZNSolsEPFRSoS_E@plt>
    1353:       90                      nop
    1354:       c9                      leaveq 
    1355:       c3                      retq   

0000000000001356 <_ZN6ObjectD1Ev>:
    1356:       f3 0f 1e fa             endbr64 
    135a:       55                      push   %rbp
    135b:       48 89 e5                mov    %rsp,%rbp
    135e:       48 83 ec 10             sub    $0x10,%rsp
    1362:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
    1366:       48 8d 35 a1 0c 00 00    lea    0xca1(%rip),%rsi        # 200e <_ZStL19piecewise_construct+0xa>
    136d:       48 8d 3d cc 2c 00 00    lea    0x2ccc(%rip),%rdi        # 4040 <_ZSt4cout@@GLIBCXX_3.4>
    1374:       e8 37 fd ff ff          callq  10b0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
    1379:       48 89 c2                mov    %rax,%rdx
    137c:       48 8b 05 4d 2c 00 00    mov    0x2c4d(%rip),%rax        # 3fd0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
    1383:       48 89 c6                mov    %rax,%rsi
    1386:       48 89 d7                mov    %rdx,%rdi
    1389:       e8 32 fd ff ff          callq  10c0 <_ZNSolsEPFRSoS_E@plt>
    138e:       90                      nop
    138f:       c9                      leaveq 
    1390:       c3                      retq   
    1391:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
    1398:       00 00 00 
    139b:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

00000000000013a0 <__libc_csu_init>:
    13a0:       f3 0f 1e fa             endbr64 
    13a4:       41 57                   push   %r15
    13a6:       4c 8d 3d bb 29 00 00    lea    0x29bb(%rip),%r15        # 3d68 <__frame_dummy_init_array_entry>
    13ad:       41 56                   push   %r14
    13af:       49 89 d6                mov    %rdx,%r14
    13b2:       41 55                   push   %r13
    13b4:       49 89 f5                mov    %rsi,%r13
    13b7:       41 54                   push   %r12
    13b9:       41 89 fc                mov    %edi,%r12d
    13bc:       55                      push   %rbp
    13bd:       48 8d 2d b4 29 00 00    lea    0x29b4(%rip),%rbp        # 3d78 <__do_global_dtors_aux_fini_array_entry>
    13c4:       53                      push   %rbx
    13c5:       4c 29 fd                sub    %r15,%rbp
    13c8:       48 83 ec 08             sub    $0x8,%rsp
    13cc:       e8 2f fc ff ff          callq  1000 <_init>
    13d1:       48 c1 fd 03             sar    $0x3,%rbp
    13d5:       74 1f                   je     13f6 <__libc_csu_init+0x56>
    13d7:       31 db                   xor    %ebx,%ebx
    13d9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    13e0:       4c 89 f2                mov    %r14,%rdx
    13e3:       4c 89 ee                mov    %r13,%rsi
    13e6:       44 89 e7                mov    %r12d,%edi
    13e9:       41 ff 14 df             callq  *(%r15,%rbx,8)
    13ed:       48 83 c3 01             add    $0x1,%rbx
    13f1:       48 39 dd                cmp    %rbx,%rbp
    13f4:       75 ea                   jne    13e0 <__libc_csu_init+0x40>
    13f6:       48 83 c4 08             add    $0x8,%rsp
    13fa:       5b                      pop    %rbx
    13fb:       5d                      pop    %rbp
    13fc:       41 5c                   pop    %r12
    13fe:       41 5d                   pop    %r13
    1400:       41 5e                   pop    %r14
    1402:       41 5f                   pop    %r15
    1404:       c3                      retq   
    1405:       66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
    140c:       00 00 00 00 

0000000000001410 <__libc_csu_fini>:
    1410:       f3 0f 1e fa             endbr64 
    1414:       c3                      retq   

Disassembly of section .fini:

0000000000001418 <_fini>:
    1418:       f3 0f 1e fa             endbr64 
    141c:       48 83 ec 08             sub    $0x8,%rsp
    1420:       48 83 c4 08             add    $0x8,%rsp
    1424:       c3                      retq  

區域物件的構造和析構

首先我們找到main函式的反匯編代碼:

00000000000011e9 <main>:
    11e9:       f3 0f 1e fa             endbr64 
    11ed:       55                      push   %rbp
    11ee:       48 89 e5                mov    %rsp,%rbp
    11f1:       48 83 ec 10             sub    $0x10,%rsp
    11f5:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
    11fc:       00 00 
    11fe:       48 89 45 f8             mov    %rax,-0x8(%rbp)
    1202:       31 c0                   xor    %eax,%eax
    1204:       48 8d 45 f4             lea    -0xc(%rbp),%rax
    1208:       be 02 00 00 00          mov    $0x2,%esi
    120d:       48 89 c7                mov    %rax,%rdi
    1210:       e8 e7 00 00 00          callq  12fc <_ZN6ObjectC1Ei>
    1215:       48 8d 45 f4             lea    -0xc(%rbp),%rax
    1219:       48 89 c7                mov    %rax,%rdi
    121c:       e8 35 01 00 00          callq  1356 <_ZN6ObjectD1Ev>
    1221:       b8 00 00 00 00          mov    $0x0,%eax
    1226:       48 8b 55 f8             mov    -0x8(%rbp),%rdx
    122a:       64 48 33 14 25 28 00    xor    %fs:0x28,%rdx
    1231:       00 00 
    1233:       74 05                   je     123a <main+0x51>
    1235:       e8 96 fe ff ff          callq  10d0 <__stack_chk_fail@plt>
    123a:       c9                      leaveq 
    123b:       c3                      retq   
從main函式的反匯編代碼中,我們可以看出,在main函式只構造了o2這一個物件,o2的建構式被命名為 _ZN6ObjectC1Ei,解構式被命名為 _ZN6ObjectD1Ev,

第10行,將物件的地址傳遞給rax暫存器,

第11行,將括號中的引數傳遞給暫存器esi,

第12行,將rax暫存器的地址傳遞給隱藏引數&obj(this指標),

在第16行,呼叫解構式,釋放函式占用的資源,

建構式:

00000000000012fc <_ZN6ObjectC1Ei>:
    12fc:       f3 0f 1e fa             endbr64 
    1300:       55                      push   %rbp
    1301:       48 89 e5                mov    %rsp,%rbp
    1304:       48 83 ec 10             sub    $0x10,%rsp
    1308:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
    130c:       89 75 f4                mov    %esi,-0xc(%rbp)
    130f:       48 8b 45 f8             mov    -0x8(%rbp),%rax
    1313:       8b 55 f4                mov    -0xc(%rbp),%edx
    1316:       89 10                   mov    %edx,(%rax)
    1318:       48 8d 35 e6 0c 00 00    lea    0xce6(%rip),%rsi        # 2005 <_ZStL19piecewise_construct+0x1>
    131f:       48 8d 3d 1a 2d 00 00    lea    0x2d1a(%rip),%rdi        # 4040 <_ZSt4cout@@GLIBCXX_3.4>
    1326:       e8 85 fd ff ff          callq  10b0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
    132b:       48 89 c2                mov    %rax,%rdx
    132e:       48 8b 45 f8             mov    -0x8(%rbp),%rax
    1332:       8b 00                   mov    (%rax),%eax
    1334:       89 c6                   mov    %eax,%esi
    1336:       48 89 d7                mov    %rdx,%rdi
    1339:       e8 b2 fd ff ff          callq  10f0 <_ZNSolsEi@plt>
    133e:       48 89 c2                mov    %rax,%rdx
    1341:       48 8b 05 88 2c 00 00    mov    0x2c88(%rip),%rax        # 3fd0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
    1348:       48 89 c6                mov    %rax,%rsi
    134b:       48 89 d7                mov    %rdx,%rdi
    134e:       e8 6d fd ff ff          callq  10c0 <_ZNSolsEPFRSoS_E@plt>
    1353:       90                      nop
    1354:       c9                      leaveq 
    1355:       c3                      retq   

解構式:

0000000000001356 <_ZN6ObjectD1Ev>:
    1356:       f3 0f 1e fa             endbr64 
    135a:       55                      push   %rbp
    135b:       48 89 e5                mov    %rsp,%rbp
    135e:       48 83 ec 10             sub    $0x10,%rsp
    1362:       48 89 7d f8             mov    %rdi,-0x8(%rbp)
    1366:       48 8d 35 a1 0c 00 00    lea    0xca1(%rip),%rsi        # 200e <_ZStL19piecewise_construct+0xa>
    136d:       48 8d 3d cc 2c 00 00    lea    0x2ccc(%rip),%rdi        # 4040 <_ZSt4cout@@GLIBCXX_3.4>
    1374:       e8 37 fd ff ff          callq  10b0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
    1379:       48 89 c2                mov    %rax,%rdx
    137c:       48 8b 05 4d 2c 00 00    mov    0x2c4d(%rip),%rax        # 3fd0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
    1383:       48 89 c6                mov    %rax,%rsi
    1386:       48 89 d7                mov    %rdx,%rdi
    1389:       e8 32 fd ff ff          callq  10c0 <_ZNSolsEPFRSoS_E@plt>
    138e:       90                      nop
    138f:       c9                      leaveq 
    1390:       c3                      retq   
    1391:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
    1398:       00 00 00 
    139b:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

全域物件的構造和析構

從上述代碼可以看出,區域物件o2的構造和析構在main函式中,

那么全域物件o1和o3的構造和析構在哪呢?

我們發現存在名字為<_Z41__static_initialization_and_destruction_0ii>的匯編代碼:

000000000000123c <_Z41__static_initialization_and_destruction_0ii>:
    123c:       f3 0f 1e fa             endbr64 
    1240:       55                      push   %rbp
    1241:       48 89 e5                mov    %rsp,%rbp
    1244:       48 83 ec 10             sub    $0x10,%rsp
    1248:       89 7d fc                mov    %edi,-0x4(%rbp)
    124b:       89 75 f8                mov    %esi,-0x8(%rbp)
    124e:       83 7d fc 01             cmpl   $0x1,-0x4(%rbp)
    1252:       0f 85 88 00 00 00       jne    12e0 <_Z41__static_initialization_and_destruction_0ii+0xa4>
    1258:       81 7d f8 ff ff 00 00    cmpl   $0xffff,-0x8(%rbp)
    125f:       75 7f                   jne    12e0 <_Z41__static_initialization_and_destruction_0ii+0xa4>
    1261:       48 8d 3d f4 2e 00 00    lea    0x2ef4(%rip),%rdi        # 415c <_ZStL8__ioinit>
    1268:       e8 73 fe ff ff          callq  10e0 <_ZNSt8ios_base4InitC1Ev@plt>
    126d:       48 8d 15 94 2d 00 00    lea    0x2d94(%rip),%rdx        # 4008 <__dso_handle>
    1274:       48 8d 35 e1 2e 00 00    lea    0x2ee1(%rip),%rsi        # 415c <_ZStL8__ioinit>
    127b:       48 8b 05 76 2d 00 00    mov    0x2d76(%rip),%rax        # 3ff8 <_ZNSt8ios_base4InitD1Ev@GLIBCXX_3.4>
    1282:       48 89 c7                mov    %rax,%rdi
    1285:       e8 16 fe ff ff          callq  10a0<__cxa_atexit@plt>
    128a:       be 01 00 00 00          mov    $0x1,%esi
    128f:       48 8d 3d be 2e 00 00    lea    0x2ebe(%rip),%rdi        # 4154 <o1>
    1296:       e8 61 00 00 00          callq  12fc <_ZN6ObjectC1Ei>
    129b:       48 8d 15 66 2d 00 00    lea    0x2d66(%rip),%rdx        # 4008 <__dso_handle>
    12a2:       48 8d 35 ab 2e 00 00    lea    0x2eab(%rip),%rsi        # 4154 <o1>
    12a9:       48 8d 3d a6 00 00 00    lea    0xa6(%rip),%rdi        # 1356 <_ZN6ObjectD1Ev>
    12b0:       e8 eb fd ff ff          callq  10a0<__cxa_atexit@plt>
    12b5:       be 03 00 00 00          mov    $0x3,%esi
    12ba:       48 8d 3d 97 2e 00 00    lea    0x2e97(%rip),%rdi        # 4158 <o3>
    12c1:       e8 36 00 00 00          callq  12fc <_ZN6ObjectC1Ei>
    12c6:       48 8d 15 3b 2d 00 00    lea    0x2d3b(%rip),%rdx        # 4008 <__dso_handle>
    12cd:       48 8d 35 84 2e 00 00    lea    0x2e84(%rip),%rsi        # 4158 <o3>
    12d4:       48 8d 3d 7b 00 00 00    lea    0x7b(%rip),%rdi        # 1356 <_ZN6ObjectD1Ev>
    12db:       e8 c0 fd ff ff          callq  10a0<__cxa_atexit@plt>
    12e0:       90                      nop
    12e1:       c9                      leaveq 
    12e2:       c3                      retq   

靜態物件(全域物件)初始化和析構,

第21行呼叫建構式,

第25行呼叫回呼函式,

第28行呼叫建構式,

在這個函式中呼叫了靜態物件(全域物件)的建構式,并且將其解構式通過_cxa_atexit函式注冊,使其能在exit時呼叫,


 00000000000012e3 <_GLOBAL__sub_I_o1>:
    12e3:       f3 0f 1e fa             endbr64 
    12e7:       55                      push   %rbp
    12e8:       48 89 e5                mov    %rsp,%rbp
    12eb:       be ff ff 00 00          mov    $0xffff,%esi
    12f0:       bf 01 00 00 00          mov    $0x1,%edi
    12f5:       e8 42 ff ff ff          callq  123c <_Z41__static_initialization_and_destruction_0ii>
    12fa:       5d                      pop    %rbp
    12fb:       c3                      retq   

_GLOBAL__sub_I_o1函式負責本編譯單元所有全域\靜態物件的構造和析構,那么這個函式在哪里被呼叫的呢?我們下面將查看程式是在哪開始執行的,

實際上在Linux環境下,glibc程式執行的入口地址是_start,這個入口是由ld聯結器默認的鏈接腳本所指定的,當然也可以通過相關引數設定自己的入口,

程式的入口

程式入口:_start

0000000000001100 <_start>:
    1100:       f3 0f 1e fa             endbr64 
    1104:       31 ed                   xor    %ebp,%ebp
    1106:       49 89 d1                mov    %rdx,%r9
    1109:       5e                      pop    %rsi
    110a:       48 89 e2                mov    %rsp,%rdx
    110d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
    1111:       50                      push   %rax
    1112:       54                      push   %rsp
    1113:       4c 8d 05 f6 02 00 00    lea    0x2f6(%rip),%r8        # 1410 <__libc_csu_fini>
    111a:       48 8d 0d 7f 02 00 00    lea    0x27f(%rip),%rcx        # 13a0 <__libc_csu_init>
    1121:       48 8d 3d c1 00 00 00    lea    0xc1(%rip),%rdi        # 11e9 <main>
    1128:       ff 15 b2 2e 00 00       callq  *0x2eb2(%rip)        # 3fe0 <__libc_start_main@GLIBC_2.2.5>
    112e:       f4                      hlt    
    112f:       90                      nop

匯編中的注釋非常清晰,

第12行才是main函式的地址,

__ libc_csu_init函式的地址是全域物件構造的地址,

__ libc_csu_fini是全域物件析構的地址,

從_ start的匯編代碼可以看出,實際上_ start函式里面呼叫了_ libc_start_main函式,并把_libc_csu_init函式和__libc_csu_fini函式以及main函式的地址作為引數傳遞進去,

由于__libc_start_main函式是在glibc元件里的函式,所以可執行檔案的反匯編代碼中并沒有這一部分的代碼,不過我們只需要大概了解其中先后呼叫關系如下:

--->_start

? --->_lib_start_main

? --->__ libc_csu_init

? --->main

? --->__libc_csu_fini

_libc_csu_init函式

00000000000013a0 <__libc_csu_init>:
    13a0:       f3 0f 1e fa             endbr64 
    13a4:       41 57                   push   %r15
    13a6:       4c 8d 3d bb 29 00 00    lea    0x29bb(%rip),%r15        # 3d68 <__frame_dummy_init_array_entry>
    13ad:       41 56                   push   %r14
    13af:       49 89 d6                mov    %rdx,%r14
    13b2:       41 55                   push   %r13
    13b4:       49 89 f5                mov    %rsi,%r13
    13b7:       41 54                   push   %r12
    13b9:       41 89 fc                mov    %edi,%r12d
    13bc:       55                      push   %rbp
    13bd:       48 8d 2d b4 29 00 00    lea    0x29b4(%rip),%rbp        # 3d78 <__do_global_dtors_aux_fini_array_entry>
    13c4:       53                      push   %rbx
    13c5:       4c 29 fd                sub    %r15,%rbp
    13c8:       48 83 ec 08             sub    $0x8,%rsp
    13cc:       e8 2f fc ff ff          callq  1000 <_init>
    13d1:       48 c1 fd 03             sar    $0x3,%rbp
    13d5:       74 1f                   je     13f6 <__libc_csu_init+0x56>
    13d7:       31 db                   xor    %ebx,%ebx
    13d9:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)
    13e0:       4c 89 f2                mov    %r14,%rdx
    13e3:       4c 89 ee                mov    %r13,%rsi
    13e6:       44 89 e7                mov    %r12d,%edi
    13e9:       41 ff 14 df             callq  *(%r15,%rbx,8)
    13ed:       48 83 c3 01             add    $0x1,%rbx
    13f1:       48 39 dd                cmp    %rbx,%rbp
    13f4:       75 ea                   jne    13e0 <__libc_csu_init+0x40>
    13f6:       48 83 c4 08             add    $0x8,%rsp
    13fa:       5b                      pop    %rbx
    13fb:       5d                      pop    %rbp
    13fc:       41 5c                   pop    %r12
    13fe:       41 5d                   pop    %r13
    1400:       41 5e                   pop    %r14
    1402:       41 5f                   pop    %r15
    1404:       c3                      retq   
    1405:       66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
    140c:       00 00 00 00 

光看匯編代碼有點難以理解,我們可以去查看glibc的源代碼中的__libc_csu_init函式,其中關鍵代碼部分:

void __libc_csu_init (int argc, char **argv, char **envp){
...
const size_t size = __init_array_end - __init_array_start;
  for (size_t i = 0; i < size; i++)
      (*__init_array_start [i]) (argc, argv, envp);     //事實上這個__init_array_satrt陣列中就有全域物件建構式的地址
}
...
}

可以看出,__ libc_csu_init函式中會將__init_array_start陣列中每個指標指向的函式執行一遍,

現在回到原來的問題,負責本編譯單元所有全域\靜態物件的構造和析構的_GLOBAL__sub_I_o1函式的指標被保存在__init_array_start陣列中,也就是在__libc_csu_init函式中被呼叫的,

那么_GLOBAL__sub_I_o1函式的指標怎么被放進 __ init_array_start陣列的呢?答案是,一旦一個目標檔案里有一個這樣的函式,編譯器會在這個編譯單元產生的目標檔案(.o)檔案的“.init_array”段中放置一個指標,這個指標指向的就是_GLOBAL__sub_I_a1函式,

//objdump -s 
......
Contents of section .init_array:
 600dc8 b0054000 00000000 2d064000 00000000  [email protected].@.....
......

析構

在__lib_start_main 函式執行完main函式之后,執行exit函式:

void exit(int status){
    while(__exit_func != NULL){
        ...
        __exit_funcs = __exit_funcs->next;      //__exit_funcs是存盤由_cxa_atexit組成的函式的鏈表,
                                                //這里的while回圈則遍歷該鏈表并逐個呼叫這些注冊的函式    
    }
    ...
    _exit(status);                              //呼叫exit系統呼叫,行程直接結束
}

總結

--->_start

? --->_lib_start_main

? --->__ libc_csu_init

? --->main

? --->__libc_csu_fini

_start
---> _libc_start_main    
------> _libc_csu_init
---------> _GLOBAL__sub_I_o1
------------> _Z41__static_initialization_and_destruction_0ii
---------------> _ZN6ObjectC1Ei  #全域建構式
------> main                #main函式
------> exit
---------> _ZN6ObjectD1Ev        #全域解構式

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/541794.html

標籤:C++

上一篇:P1005 [NOIP2007 提高組] 矩陣取數游戲

下一篇:【線段樹】動態開點

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more