c语言 数据交换的 汇编代码解析

我们都知道数据x ,y 的值交换,可以用到c 指针来实现,
具体到汇编层面,是如何实现的呢。
请看下面的例子:

1、建立一个point.c 文件,来实现x 和y 值的交换。

vi point.c

#include <stdio.h>
void change(int *x, int *y){
    int z = *x;
    *x = *y;
    *y = z;
}
 
int main()
{   
   int x = 10;
   int y =20; 
   change(&x, &y);
   printf("x=%d,y=%d \n", x, y);
    return 0;
}

2、编译为.o 文件
#gcc -c  point.c
 
3、汇编反编译成文本

#objdump -d point.o

 

point.o:     file format elf64-x86-64
Disassembly of section .text:
change 函数
0000000000000000 <change>:
   0:    55                       push   %rbp
   1:    48 89 e5                 mov    %rsp,%rbp
   4:    48 89 7d e8              mov    %rdi,-0x18(%rbp)  x的地址
   8:    48 89 75 e0              mov    %rsi,-0x20(%rbp)  y的地址
   c:    48 8b 45 e8              mov    -0x18(%rbp),%rax  x的地址⇒%rax 
  10:    8b 00                    mov    (%rax),%eax       z = *x  
  12:    89 45 fc                 mov    %eax,-0x4(%rbp)   z ⇒ -0x4(%rbp)
  15:    48 8b 45 e0              mov    -0x20(%rbp),%rax  y的地址⇒%rax 
  19:    8b 10                    mov    (%rax),%edx       y的值⇒%edx 
  1b:    48 8b 45 e8              mov    -0x18(%rbp),%rax  x的地址⇒%rax 
  1f:    89 10                    mov    %edx,(%rax)       y的值(%edx) ⇒x    *x = *y;
  21:    48 8b 45 e0              mov    -0x20(%rbp),%rax  y的地址⇒%rax 
  25:    8b 55 fc                 mov    -0x4(%rbp),%edx   z的值(-0x4(%rbp)) ⇒%edx 
  28:    89 10                    mov    %edx,(%rax)        z的值(%edx) ⇒y   *y = z;
  2a:    c9                       leaveq 
  2b:    c3                       retq   

main 函数
000000000000002c <main>:
  2c:    55                       push   %rbp
  2d:    48 89 e5                 mov    %rsp,%rbp
  30:    48 83 ec 10              sub    $0x10,%rsp
  34:    c7 45 fc 0a 00 00 00     movl   $0xa,-0x4(%rbp)     int x = 10;
  3b:    c7 45 f8 14 00 00 00     movl   $0x14,-0x8(%rbp)    int y =20; 
  42:    48 8d 55 f8              lea    -0x8(%rbp),%rdx     y 的地址 ⇒%rdx 
  46:    48 8d 45 fc              lea    -0x4(%rbp),%rax     x 的地址 ⇒%rax 
  4a:    48 89 d6                 mov    %rdx,%rsi           y 的地址 ⇒%rsi  (地址参数y)
  4d:    48 89 c7                 mov    %rax,%rdi           x 的地址 ⇒%rdi (地址参数x)
  50:    e8 00 00 00 00           callq  55 <main+0x29>
  55:    8b 55 f8                 mov    -0x8(%rbp),%edx
  58:    8b 4d fc                 mov    -0x4(%rbp),%ecx
  5b:    b8 00 00 00 00           mov    $0x0,%eax
  60:    89 ce                    mov    %ecx,%esi
  62:    48 89 c7                 mov    %rax,%rdi
  65:    b8 00 00 00 00           mov    $0x0,%eax
  6a:    e8 00 00 00 00           callq  6f <main+0x43>
  6f:    b8 00 00 00 00           mov    $0x0,%eax
  74:    c9                       leaveq 
  75:    c3                       retq  

从以上例子可以看出,地址传递,是把变量的地址,作为参数传递过去了。

change 函数里面,直接把x,y 的地址中的值通过变量z 来进行了交换。

change 退出时没有参数返回,因为x,y 的地址(也就是main 中的 x,y 栈地址)中保存的值,已经发生了交换。

 

转载于:https://www.cnblogs.com/snail88/p/7464239.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值