源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

c文件汇编后函数参数传递的不同之处

  • 时间:2021-01-06 07:31 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:c文件汇编后函数参数传递的不同之处
mac下clang编译后函数的参数先保存在寄存器中(以一定的规则保存),然后在函数中压入栈里, 以待后用。例如上篇例子,红色部分:
[u]复制代码[/u] 代码如下:
.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:
[u]复制代码[/u] 代码如下:
int hello(int a,int b,int c,int d) {     return b; }
test.c
[u]复制代码[/u] 代码如下:
.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例子:
[u]复制代码[/u] 代码如下:
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 后:
[u]复制代码[/u] 代码如下:
.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:
[u]复制代码[/u] 代码如下:
//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); }
汇编后完全一样:
[u]复制代码[/u] 代码如下:
.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]没什么不同,只用在栈中才会有所不同。 学习汇编不是必要,但是它可以让我们知道效率。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部