a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

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

2020-01-26 15:42:25
字體:
來源:轉載
供稿:網友

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

復制代碼 代碼如下:

.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使用了兩種不同的規則(網上有很多介紹函數值傳遞的不同規則的,我就不介紹了)。
所以不同的平臺不同的編譯器要不同的對待。以上算是上次的不足補充吧。
下面來看看數組:
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]沒什么不同,只用在棧中才會有所不同。
學習匯編不是必要,但是它可以讓我們知道效率。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 激情五月综合 | 日韩www. | 在线不卡av | 国产精品久久久久久久久久久久久久 | 精品久久影院 | 日韩一级不卡 | 欧美一区永久视频免费观看 | 91麻豆精品国产91久久久资源速度 | 2019精品手机国产品在线 | 91av久久| 国产视频久久久 | 色婷婷电影 | 国产精品精品视频一区二区三区 | 国产激情的老师在线播放 | 亚洲天堂一区 | 欧美成亚洲 | 久久人妖| 日韩特黄一级欧美毛片特黄 | 免费看一区二区三区 | 日本免费久久 | 欧美一区二区三区免费 | 精品国产高清一区二区三区 | 波多野结衣一区在线观看 | 99久久精品国产一区二区成人 | 激情综合色 | 美女黄色毛片视频 | av大片在线免费观看 | 久久久久久久久久久久福利 | 国产日韩欧美精品一区 | 日本精品一区二区三区视频 | 一区二区三区国产视频 | 成人在线免费观看视频 | 大片黄网站| 免费观看成人羞羞视频网站观看 | 久久久一区二区三区 | 日韩1区2区3区 | 夜夜艹| 精品国产欧美一区二区 | 日韩成人在线免费视频 | 一区二区成人 | 91精品久久久久久久久久入口 |