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

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

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

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

復制代碼 代碼如下:

.global _decToBin

 _decToBin:
     pushq     %rbp
     movq    %rsp,%rbp

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

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

......

     popq     %rbp
     ret

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

test.c:

復制代碼 代碼如下:

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

test.c
復制代碼 代碼如下:

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

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

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]; //這也對?
}

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

.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:
復制代碼 代碼如下:

//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);
}

匯編后完全一樣:
復制代碼 代碼如下:

.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]沒什么不同,只用在棧中才會有所不同。
學習匯編不是必要,但是它可以讓我們知道效率。

相關文章

  • c++11可變參數使用示例

    c++11可變參數使用示例

    這篇文章主要介紹了c++11可變參數使用示例,需要的朋友可以參考下
    2014-03-03
  • C++實現inline hook的原理及應用實例

    C++實現inline hook的原理及應用實例

    這篇文章主要介紹了C++實現inline hook的原理及應用,需要的朋友可以參考下
    2014-08-08
  • C語言中settimeofday函數和gettimeofday函數的使用

    C語言中settimeofday函數和gettimeofday函數的使用

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

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

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

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

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

    淺談返回函數內部new分配的內存的引用

    下面小編就為大家?guī)硪黄獪\談返回函數內部new分配的內存的引用。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • C++編程中指針的聲明與基本使用講解

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

    這篇文章主要介紹了詳解C++編程中C++編程中指針的聲明與基本使用講解,文中舉了簡單的例子來講如何在基本的數據結構中使用指針,以及固定和可變指針的介紹,需要的朋友可以參考下
    2016-01-01
  • 深入了解一下C語言中的柔性數組

    深入了解一下C語言中的柔性數組

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

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

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

    C++?this原理與可變參數及友元函數友元類分步詳解用法

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

最新評論