最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c文件匯編后函數(shù)參數(shù)傳遞的不同之處

 更新時間:2013年11月15日 15:15:02   作者:  
在w7 32位系統(tǒng)下把c文件匯編后,確實與mac后的差異很大??刹粌H僅是寄存器eax與rax的區(qū)別。我想說的是函數(shù)參數(shù)傳遞的不同

mac下clang編譯后函數(shù)的參數(shù)先保存在寄存器中(以一定的規(guī)則保存),然后在函數(shù)中壓入棧里,
以待后用。例如上篇例子,紅色部分:

復(fù)制代碼 代碼如下:

.global _decToBin

 _decToBin:
     pushq     %rbp
     movq    %rsp,%rbp

     movq     %rdi,-8(%rbp) #第一個參數(shù),保存在rdi中
     movq     %rsi,-16(%rbp) #第二個參數(shù),保存在rsi中

     movq    -8(%rbp),%rax
     movq    -16(%rbp),%rbx
     movq    $63,%rcx

......

     popq     %rbp
     ret

而我在w7下使用cygwin安裝的gcc編譯test.c文件:

test.c:

復(fù)制代碼 代碼如下:

int hello(int a,int b,int c,int d)
{
    return b;
}

test.c
復(fù)制代碼 代碼如下:

.file    "test.c"
    .text
    .globl    _hello
    .def    _hello;    .scl    2;    .type    32;    .endef
_hello:
    pushl    %ebp
    movl    %esp, %ebp
    movl    12(%ebp), %eax #說明參數(shù)是函數(shù)在使用其值之前就已經(jīng)壓入棧中
    popl    %ebp
    ret

這說明clang與gcc使用了兩種不同的規(guī)則(網(wǎng)上有很多介紹函數(shù)值傳遞的不同規(guī)則的,我就不介紹了)。
所以不同的平臺不同的編譯器要不同的對待。以上算是上次的不足補(bǔ)充吧。
下面來看看數(shù)組:
test.c例子:
復(fù)制代碼 代碼如下:

void hello1()
{
    int a[3]={1,2,3};
        int b=a[1];
}
void hello2()
{
    int a[3]={1,2,3};
    int b=*(a+1);
}
void hello3()
{
    int a[3]={1,2,3};
    int b=1[a]; //這也對?
}

如果看的夠仔細(xì)的話,三個函數(shù)沒什么不同就是對數(shù)組a[1]的不同(當(dāng)然函數(shù)名除外).
gcc -S test.c 后:
復(fù)制代碼 代碼如下:

.file    "test.c"
    .data
    .align 4
LC0:
    .long    1
    .long    2
    .long    3
    .text
    .globl    _hello1
    .def    _hello1;    .scl    2;    .type    32;    .endef
_hello1:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %edi
    pushl    %esi
    pushl    %ebx
    subl    $16, %esp
    leal    -28(%ebp), %edx
    movl    $LC0, %ebx
    movl    $3, %eax
    movl    %edx, %edi
    movl    %ebx, %esi
    movl    %eax, %ecx
    rep movsl
    movl    -24(%ebp), %eax
    movl    %eax, -16(%ebp)
    addl    $16, %esp
    popl    %ebx
    popl    %esi
    popl    %edi
    popl    %ebp
    ret
    .globl    _hello2
    .def    _hello2;    .scl    2;    .type    32;    .endef
_hello2:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %edi
    pushl    %esi
    pushl    %ebx
    subl    $16, %esp
    leal    -28(%ebp), %edx
    movl    $LC0, %ebx
    movl    $3, %eax
    movl    %edx, %edi
    movl    %ebx, %esi
    movl    %eax, %ecx
    rep movsl
    leal    -28(%ebp), %eax
    movl    4(%eax), %eax
    movl    %eax, -16(%ebp)
    addl    $16, %esp
    popl    %ebx
    popl    %esi
    popl    %edi
    popl    %ebp
    ret
    .globl    _hello3
    .def    _hello3;    .scl    2;    .type    32;    .endef
_hello3:
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %edi
    pushl    %esi
    pushl    %ebx
    subl    $16, %esp
    leal    -28(%ebp), %edx
    movl    $LC0, %ebx
    movl    $3, %eax
    movl    %edx, %edi
    movl    %ebx, %esi
    movl    %eax, %ecx
    rep movsl
    movl    -24(%ebp), %eax
    movl    %eax, -16(%ebp)
    addl    $16, %esp
    popl    %ebx
    popl    %esi
    popl    %edi
    popl    %ebp
    ret

只要看紅色的行,我們可以看到25-27行與74-76行一樣,說明hello1與hello3沒什么不同,
效率一樣。而49-52行比他們多了一行,所以*(a+1)比a[1]和1[a]要低一點。
但是我們看下面的例子。
test1.c與test2.c:
復(fù)制代碼 代碼如下:

//1--------------
#include <stdlib.h>
void hello()
{
    int *a=(int*)malloc(sizeof(int)*3);
    int b=*(a+1);
    free(a);
}
 //2--------------
#include <stdlib.h>
void hello()
{
    int *a=(int*)malloc(sizeof(int)*3);
    int b=a[1];
    free(a);
}

匯編后完全一樣:
復(fù)制代碼 代碼如下:

.file    "main.c"
    .text
    .globl    _hello
    .def    _hello;    .scl    2;    .type    32;    .endef
_hello:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $40, %esp
    movl    $12, (%esp)
    call    _malloc
    movl    %eax, -12(%ebp)
    movl    -12(%ebp), %eax
    movl    4(%eax), %eax
    movl    %eax, -16(%ebp)
    leave
    ret
    .def    _malloc;    .scl    2;    .type    32;    .endef

所以在堆中使用*(a+n)與a[n]沒什么不同,只用在棧中才會有所不同。
學(xué)習(xí)匯編不是必要,但是它可以讓我們知道效率。

相關(guān)文章

  • C語言實現(xiàn)常見進(jìn)制轉(zhuǎn)換的示例代碼

    C語言實現(xiàn)常見進(jìn)制轉(zhuǎn)換的示例代碼

    生活中最常見的進(jìn)制是十進(jìn)制,而有一類編程題會要求將十進(jìn)制轉(zhuǎn)換為其他進(jìn)制,本文將主要講述C語言中常見的幾類進(jìn)制轉(zhuǎn)換問題,希望對大家有所幫助
    2023-04-04
  • C語言中的運算符優(yōu)先級和結(jié)合性一覽表

    C語言中的運算符優(yōu)先級和結(jié)合性一覽表

    這篇文章主要介紹了C語言中的運算符優(yōu)先級和結(jié)合性一覽表,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 詳解C++中的一維數(shù)組和二維數(shù)組

    詳解C++中的一維數(shù)組和二維數(shù)組

    這篇文章主要介紹了詳解C++中的一維數(shù)組和二維數(shù)組,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • c 調(diào)用python出現(xiàn)異常的原因分析

    c 調(diào)用python出現(xiàn)異常的原因分析

    本篇文章是對使用c語言調(diào)用python出現(xiàn)異常的原因進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++多線程互斥鎖和條件變量的詳解

    C++多線程互斥鎖和條件變量的詳解

    這篇文章主要為大家詳細(xì)介紹了C++多線程互斥鎖和條件變量,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++中關(guān)于多態(tài)實現(xiàn)和使用方法

    C++中關(guān)于多態(tài)實現(xiàn)和使用方法

    這篇文章主要介紹了C++中關(guān)于多態(tài)實現(xiàn)和使用方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • 神奇的c/c++小游戲((提高你的編程興趣)

    神奇的c/c++小游戲((提高你的編程興趣)

    本文通過c/c++編寫小游戲,可以提高新手們的編程興趣,接下來我們一起來看看吧
    2021-08-08
  • C語言實現(xiàn)學(xué)生檔案管理系統(tǒng)

    C語言實現(xiàn)學(xué)生檔案管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實現(xiàn)學(xué)生檔案管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言中strcpy和strcat的使用和模擬實現(xiàn)

    C語言中strcpy和strcat的使用和模擬實現(xiàn)

    strcpy()?函數(shù)是?C語言中一個非常重要的字符串處理函數(shù),其功能是將一個字符串復(fù)制到另一個字符串中,strcat函數(shù)可以將一個字符串拼接到另一個字符串的末尾,本文給大家介紹了C語言中strcpy和strcat的使用和模擬實現(xiàn),需要的朋友可以參考下
    2024-03-03
  • C++基于字符串實現(xiàn)大數(shù)相乘問題的代碼詳解

    C++基于字符串實現(xiàn)大數(shù)相乘問題的代碼詳解

    在實際編程中,我們經(jīng)常會遇到需要處理大整數(shù)的情況,由于編程語言中內(nèi)置整數(shù)類型有其表示范圍的限制,當(dāng)需要處理的整數(shù)超出這些范圍時,就不能直接使用內(nèi)置類型進(jìn)行計算,所以本文給大家介紹了相關(guān)的解決方法,需要的朋友可以參考下
    2025-03-03

最新評論

彭水| 闽清县| 仙游县| 永康市| 和林格尔县| 马山县| 太仆寺旗| 梁河县| 孟连| 寿阳县| 贺兰县| 商丘市| 磴口县| 秦安县| 营口市| 汉中市| 丰都县| 潞城市| 滦平县| 包头市| 马公市| 巴彦县| 昆山市| 府谷县| 社旗县| 磐石市| 大同市| 镇平县| 长垣县| 监利县| 新邵县| 奎屯市| 穆棱市| 城口县| 罗城| 雅安市| 阿荣旗| 贵阳市| 包头市| 昌乐县| 长顺县|