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

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

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

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

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

.global _decToBin

 _decToBin:
     pushq     %rbp
     movq    %rsp,%rbp

     movq     %rdi,-8(%rbp) #第一個(gè)參數(shù),保存在rdi中
     movq     %rsi,-16(%rbp) #第二個(gè)參數(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 #說(shuō)明參數(shù)是函數(shù)在使用其值之前就已經(jīng)壓入棧中
    popl    %ebp
    ret

這說(shuō)明clang與gcc使用了兩種不同的規(guī)則(網(wǎng)上有很多介紹函數(shù)值傳遞的不同規(guī)則的,我就不介紹了)。
所以不同的平臺(tái)不同的編譯器要不同的對(duì)待。以上算是上次的不足補(bǔ)充吧。
下面來(lái)看看數(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]; //這也對(duì)?
}

如果看的夠仔細(xì)的話,三個(gè)函數(shù)沒(méi)什么不同就是對(duì)數(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行一樣,說(shuō)明hello1與hello3沒(méi)什么不同,
效率一樣。而49-52行比他們多了一行,所以*(a+1)比a[1]和1[a]要低一點(diǎn)。
但是我們看下面的例子。
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]沒(méi)什么不同,只用在棧中才會(huì)有所不同。
學(xué)習(xí)匯編不是必要,但是它可以讓我們知道效率。

相關(guān)文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

最新評(píng)論

广宁县| 扬中市| 台州市| 马边| 芜湖市| 永福县| 儋州市| 濮阳县| 常宁市| 邹城市| 宣城市| 郧西县| 望江县| 含山县| 平遥县| 泸水县| 甘孜| 射洪县| 新干县| 和林格尔县| 连城县| 新竹县| 广水市| 木兰县| 景洪市| 九龙坡区| 富阳市| 谢通门县| 电白县| 牙克石市| 兴山县| 高淳县| 工布江达县| 自治县| 横山县| 山东省| 阿坝县| 丹凤县| 微博| 五华县| 屏山县|