欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2013年11月15日 15:15:02   作者:  
在w7 32位系統(tǒng)下把c文件匯編后,確實(shí)與mac后的差異很大??刹粌H僅是寄存器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++11可變參數(shù)使用示例

    c++11可變參數(shù)使用示例

    這篇文章主要介紹了c++11可變參數(shù)使用示例,需要的朋友可以參考下
    2014-03-03
  • C++實(shí)現(xiàn)inline hook的原理及應(yīng)用實(shí)例

    C++實(shí)現(xiàn)inline hook的原理及應(yīng)用實(shí)例

    這篇文章主要介紹了C++實(shí)現(xiàn)inline hook的原理及應(yīng)用,需要的朋友可以參考下
    2014-08-08
  • C語(yǔ)言中settimeofday函數(shù)和gettimeofday函數(shù)的使用

    C語(yǔ)言中settimeofday函數(shù)和gettimeofday函數(shù)的使用

    這篇文章主要介紹了C語(yǔ)言中的settimeofday函數(shù)和gettimeofday函數(shù)的使用,注意settimeofday()函數(shù)只返回0和-1,需要的朋友可以參考下
    2015-08-08
  • C語(yǔ)言舉例講解i++與++i之間的區(qū)別

    C語(yǔ)言舉例講解i++與++i之間的區(qū)別

    這篇文章主要介紹了C語(yǔ)言中i++和++i的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)詳解

    C++的靜態(tài)成員變量和靜態(tài)成員函數(shù)詳解

    這篇文章主要為大家介紹了C++的靜態(tài)成員變量和靜態(tài)成員函數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-12-12
  • 淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用

    淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用

    下面小編就為大家?guī)?lái)一篇淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • C++編程中指針的聲明與基本使用講解

    C++編程中指針的聲明與基本使用講解

    這篇文章主要介紹了詳解C++編程中C++編程中指針的聲明與基本使用講解,文中舉了簡(jiǎn)單的例子來(lái)講如何在基本的數(shù)據(jù)結(jié)構(gòu)中使用指針,以及固定和可變指針的介紹,需要的朋友可以參考下
    2016-01-01
  • 深入了解一下C語(yǔ)言中的柔性數(shù)組

    深入了解一下C語(yǔ)言中的柔性數(shù)組

    柔性數(shù)組是在C99中定義的,即結(jié)構(gòu)體的最后一個(gè)元素允許是未知大小的數(shù)組,這就叫柔性數(shù)組。這篇文章將通過(guò)簡(jiǎn)單的示例為大家介紹一下柔性數(shù)組的使用,感興趣的可以了解一下
    2023-02-02
  • C++中繼承(inheritance)詳解及其作用介紹

    C++中繼承(inheritance)詳解及其作用介紹

    這篇文章主要介紹了C++中繼承(inheritance)詳解及其作用介紹,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C++?this原理與可變參數(shù)及友元函數(shù)友元類(lèi)分步詳解用法

    C++?this原理與可變參數(shù)及友元函數(shù)友元類(lèi)分步詳解用法

    可變參數(shù)模板(variadic?templates)是C++11新增的強(qiáng)大的特性之一,它對(duì)模板參數(shù)進(jìn)行了高度泛化,能表示0到任意個(gè)數(shù)、任意類(lèi)型的參數(shù),這篇文章主要介紹了C++?this原理與可變參數(shù)及友元函數(shù)友元類(lèi)
    2022-11-11

最新評(píng)論