汇编指针(十二)

指针基础

指针在64位占8个字节(64Bit),(比如int 占4个字节 char 1个 ,没说指针),其中指针不能乘除,只能加减运算

1.先看个简单的指针宽度

2.指针自增

指针的运算是它指向的数据类型的宽度决定,比如上面的a=104是 a+sizeof(int)所得,其中就是去掉一个指针决定,继续看下面

问题:int arr[3] = {1,2,3};  arr++;  ❌

arr本是指首地址,也就是arr=arr+1;系统不允许改动,但是可以用int *a = arr; a++来取值

3.多个指针自增

上面是2个指针,在自增的时候,首页去掉一个指针称(int *)也就是一个指针,sizeof(指针),指针宽度8个字节+100=108

4.指针运算

首页看

  1. a=100,b=200,
  2.   a-b=-100
  3. -100/sizeof(int) = -25

5.指针的比较

6.指针运算溢出

指针运算时根据所指向的数据类型算的,


指针反汇编

分析指针汇编

 

在栈上开辟4个字节的地址给x8,然后寄存器w9=10, w9入栈到栈地址向上8个字节地址。这里相对简单易懂些

注意:栈的写入读取是向高地址执行


指针基本用法

1.取没有初始化的地址

直接crash,EXC_BAD_ACCESS,可以直接调试:

lldb: register read x8

lldb: 0x0000000000…

都是0x0000000… 这个地址并没有初始化分配内存地址,在取x8地址的时候并没这个地址直接报Bad_Access,

2.sp拉伸

汇编:

问题:#mark-a sp为什么要拉伸0x20?

解:sp拉伸看func函数里 局部变量是3个指针,也就是3*sizeof(指针)=24,sp是按照16字节对齐(0x20 32字节够用),

如果在func函数里加入

  • char c;
  • int **p2;

4*8+1 = 33,sp 0x20是不够的,所以 sp拉伸必须是0x30sp是16字节对齐,其他的空着

问题:#mark-b x8为什么[x8, #0x8]偏移8字节?

因为他是指针8字节,如果是int是4自己,char为1

3.指针取值方式

汇编:

其中#mark-a, #mark-b 都是偏移8字节取值的,也就是一样的方式,(内存地址一样,反汇编代码也是一样)

比如: int n = *(p+1);     和int m = p[1]; 也是一样的

4.

解释:p+3:  p 是一个指针也就是8个字节,+3就是偏移3个8字节 x*8=24

*(p +3) +2:  取值后再加3 因为是char类型, 也就是3*sizeof(char) =24+2=26;

参考下汇编:

#mark-a  [x8, #0x18]: ox18是24字节, ox2=2 也就是和上面分析一样共偏移27字节

总结: char ch = *(*(p +3) +2);   就是等于  char ch = p[3][2]

计算指针偏移就是去掉一个*看他的类型宽度

发表回复

电子邮件地址不会被公开。 必填项已用*标注

Protected with IP Blacklist CloudIP Blacklist Cloud