反汇编一:内置数据类型

变量访问

全局变量和局部变量
变量访问
局部静态变量位置:
rip作偏移 05ae+0a92=1040

64位系统
6           static int a=0;
7           a++;
   0x00000000004005a8 <+11>:    mov    0x200a92(%rip),%eax        # 0x601040 <_ZZ4testiE1a>
   0x00000000004005ae <+17>:    add    $0x1,%eax
   0x00000000004005b1 <+20>:    mov    %eax,0x200a89(%rip)        # 0x601040 <_ZZ4testiE1a>
  x /16x 0x601040
0x601040 <_ZZ4testiE1a>:        0x00000001

局部静态变量初始化:

 static int a=0;  //不在栈中初始化
 static int a=变量; //栈中初始化,存储在栈外

在这里插入图片描述

64位系统实例
6           static int a=n;
   0x0000000000400688 <+11>:    mov    $0x601058,%eax    //标记位地址在0x601060前2个字节
   0x000000000040068d <+16>:    movzbl (%rax),%eax       //movzbl “零扩展”
  //|63..32|31..16|15-8|7-0|     rax   eax   ax   ah  al 关系
  //               |AH.|AL.|
  //               |AX.....|
  //       |EAX............|
  //|RAX...................|
   0x0000000000400690 <+19>:    test   %al,%al  //执行AND逻辑操作,设置标志寄存器 C,O,P,Z,S。
   //ZF:运算结果为0,zf为1
   0x0000000000400692 <+21>:    jne    0x4006ba <test(int)+61> //当ZF=0,转至标号处执行
   0x0000000000400694 <+23>:    mov    $0x601058,%edi
   0x0000000000400699 <+28>:    callq  0x400540 <__cxa_guard_acquire@plt>       //线程安全锁
   0x000000000040069e <+33>:    test   %eax,%eax
   0x00000000004006a0 <+35>:    setne  %al    //SETE取标志寄存器中ZF的值, 放到AL中. SETNE取得ZF值后, 取反, 再放到AL中.
   0x00000000004006a3 <+38>:    test   %al,%al  //??
   0x00000000004006a5 <+40>:    je     0x4006ba <test(int)+61>
   0x00000000004006a7 <+42>:    mov    -0x4(%rbp),%eax
   0x00000000004006aa <+45>:    mov    %eax,0x2009b0(%rip)  //初始化      # 0x601060 <_ZZ4testiE1a>
   0x00000000004006b0 <+51>:    mov    $0x601058,%edi
   0x00000000004006b5 <+56>:    callq  0x400580 <__cxa_guard_release@plt>

7           a++;
   0x00000000004006ba <+61>:    mov    0x2009a0(%rip),%eax        # 0x601060 <_ZZ4testiE1a>
   0x00000000004006c0 <+67>:    add    $0x1,%eax
   0x00000000004006c3 <+70>:    mov    %eax,0x200997(%rip)        # 0x601060 <_ZZ4testiE1a>

__cxa_guard_acquire@plt

堆变量
%rax存了地址 ,(%rax) 解引用

6           int *pnew =new(int);
   0x0000000000400668 <+11>:    mov    $0x4,%edi
   0x000000000040066d <+16>:    callq  0x400560 <_Znwm@plt>  //new  <malloc@plt>shi malloc
   0x0000000000400672 <+21>:    mov    %rax,-0x8(%rbp)

7           (*pnew)+=1;
   0x0000000000400676 <+25>:    mov    -0x8(%rbp),%rax   //pnew地址
   0x000000000040067a <+29>:    mov    (%rax),%eax      //pnew地址存的值
   0x000000000040067c <+31>:    lea    0x1(%rax),%edx   //把rax寄存器的数+0x1 传送到 edx寄存器中
   0x000000000040067f <+34>:    mov    -0x8(%rbp),%rax
   0x0000000000400683 <+38>:    mov    %edx,(%rax)    //edx为计算结果,放回地址-0x8(%rbp)

函数指针
%rax存了地址 callq *%rax跳转

...................
12          int(*p)(int);
13          p=fun;
   0x00000000004005b8 <+11>:    movq   $0x40059d,-0x8(%rbp) 地址立即数
14          return p(n);
   0x00000000004005c0 <+19>:    mov    -0x14(%rbp),%edx
   0x00000000004005c3 <+22>:    mov    -0x8(%rbp),%rax
   0x00000000004005c7 <+26>:    mov    %edx,%edi
   0x00000000004005c9 <+28>:    callq  *%rax
.................
Dump of assembler code for function fun(int):
5       {
   0x000000000040059d <+0>:     push   %rbp
................

对齐规则


对齐规则参考
自身对齐值:数据类型本身的对齐值,例如char类型的自身对齐值是1,short类型是2;
指定对齐值:编译器或程序员指定的对齐值,32位单片机的指定对齐值默认是4;
有效对齐值:自身对齐值和指定对齐值中较小的那个。
对齐有两个规则:
1、不但结构体的成员有有效对齐值,结构体本身也有对齐值,这主要是考虑结构体的数组,对于结构体或者类,要将其补齐为其有效对齐值的整数倍。结构体的有效对齐值是其最大数据成员的自身对齐值;
2、存放成员的起始地址必须是该成员有效对齐值的整数倍。

存储位置


3G
0xbfaa 5060 栈地址 2.xG
0x09b3 e008 堆地址
0x0804 84f1 代码段
0x0804 98a4 全局数据 128M多
0G

局部变量存储顺序/参数入栈顺序
栈底 往上 sp方向
高地址 往 低地址
后定义的变量 再 先定义的
简单的结构 再 复杂的结构

32位系统实例32位系统实例

#include <stdio.h>
#include <string.h>
#include <stdlib.h> 

struct dd
{
  double e;
  double f;
};
struct complexst
{
  char a;
  double b;
  char c;
  char d;
  struct dd d1;
};

unsigned int ga=305419896;
#define wrq "wrq"

int fun()
{
  
  int b=-5;
  
  char *gp=(char*)&ga;
  gp++;
  *gp=0;
  
  
  float f=1.5;
  
  int c=2147483648; //0x7FFFFFFF+1;
  
  const char a[15]={"abcdefgh"};
  
  char *hp=(char*)new(int);
  *hp='x';
  (*hp)++;
  *hp='y';
  
  char a2dem[][4]={{'a','b'},{"cde"}};
  a2dem[1][1]='x';
  
  struct complexst com1;
  com1.a=1;
  com1.b=2;
  com1.c=3;
  com1.d=4;
  com1.d1.e=5;
  com1.d1.f=5;
  
  abort();
  return 0;
}

int main(int argc, char** argv)
{
  fun();
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值