<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Chapter 8 一個或者多個字的返回值 X86架構下通常返回EAX寄存器的值,如果是單字節char,則只使用EAX的低8位AL。如果返回float類型則使用FPU寄存器ST(0)。ARM架構下通常返回寄存器R0。 假如main()函數的返回值是void而不是int會怎么樣? 通常啟動函數調用main()為: ``` #!bash push envp push argv push argc call main push eax call exit ``` 換句話說為 ``` #!cpp exit(main(argc,argv,envp)); ``` 如果main()聲明為void類型并且函數沒有明確返回狀態值,通常在main()結束時EAX寄存器的值被返回,然后作為exit()的參數。大多數情況下函數返回的是隨機值。這種情況下程序的退出代碼為偽隨機的。 我們看一個實例,注意main()是void類型: ``` #!cpp #include <stdio.h> void main() { printf ("Hello, world! "); }; ``` 我們在linux下編譯。 GCC 4.8.1會使用puts()替代printf()(看前面章節2.3.3),沒有關系,因為puts()會返回打印的字符數,就行printf()一樣。請注意,main()結束時EAX寄存器的值是非0的,這意味著main()結束時保留puts()返回時EAX的值。 Listing 8.1: GCC 4.8.1 ``` #!bash .LC0: .string "Hello, world!" main: push ebp mov ebp, esp and esp, -16 sub esp, 16 mov DWORD PTR [esp], OFFSET FLAT:.LC0 call puts leave ret ``` 我們寫bash腳本來看退出狀態: Listing 8.2: tst.sh ``` #!bash #!/bin/sh ./hello_world echo $? ``` 運行: ``` #!bash $ tst.sh Hello, world! 14 ``` 14為打印的字符數。 回到返回值是EAX寄存器值的事實,這也就是為什么老的C編譯器不能夠創建返回信息無法擬合到一個寄存器(通常是int型)的函數。如果必須這樣,應該通過指針來傳遞。現在可以這樣,比如返回整個結構體,這種情況應該避免。如果必須要返回大的結構體,調用者必須開辟存儲空間,并通過第一個參數傳遞指針,整個過程對程序是透明的。像手動通過第一個參數傳遞指針一樣,只是編譯器隱藏了這個過程。 小例子: ``` #!cpp struct s { int a; int b; int c; }; struct s get_some_values (int a) { struct s rt; rt.a=a+1; rt.b=a+2; rt.c=a+3; return rt; }; ``` …我們可以得到(MSVC 2010 /Ox): ``` #!bash $T3853 = 8 ; size = 4 _a$ = 12 ; size = 4 ?get_some_values@@YA?AUs@@H@Z PROC ; get_some_values mov ecx, DWORD PTR _a$[esp-4] mov eax, DWORD PTR $T3853[esp-4] lea edx, DWORD PTR [ecx+1] mov DWORD PTR [eax], edx lea edx, DWORD PTR [ecx+2] add ecx, 3 mov DWORD PTR [eax+4], edx mov DWORD PTR [eax+8], ecx ret 0 ?get_some_values@@YA?AUs@@H@Z ENDP ; get_some_values ``` 內部變量傳遞指針到結構體的宏為$T3853。 這個例子可以用C99語言擴展來重寫: ``` #!bash struct s { int a; int b; int c; }; struct s get_some_values (int a) { return (struct s){.a=a+1, .b=a+2, .c=a+3}; }; ``` Listing 8.3: GCC 4.8.1 ``` #!bash _get_some_values proc near ptr_to_struct = dword ptr 4 a = dword ptr 8 mov edx, [esp+a] mov eax, [esp+ptr_to_struct] lea ecx, [edx+1] mov [eax], ecx lea ecx, [edx+2] add edx, 3 mov [eax+4], ecx mov [eax+8], edx retn _get_some_values endp ``` 我們可以看到,函數僅僅填充調用者申請的結構體空間的相應字段。因此沒有性能缺陷。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看