计算机怎么知道指针指向的具体类型?

分析环境

  1. 编译器 x86-64 gcc 10.2
  2. 汇编风格 AT&T 风格

概述

汇编代码基于 x86-64 ,由于 x86 系列的 CPU 向后兼容,在指令上,兼容就是 intel8086 这个 16bit 的处理器的指令,在 intel80386 这个32bit 的处理器上也能使用。以此类推。先来了解下寄存器的变化。详细的可以查看 x86 寄存器历史

以 ax 为例

16bit32bit64bit
axeaxrax

可以了解 eax 是 32bits,rax 是 64bits。 其他指令类似。用 er来区分 32bits 还是 64bits

不同位数下的指令如何区分?

mov 为例

8bit16bit32bit64bit
movbmovwmovlmovq

可以看到使用不同的后缀来表示这个是多少 bit 的指令

CPU 如何寻址?

CPU 寻址方式, 也就是拿到数据的方式.

立即数

movb $0x05,%al
表示为:R[al] = 0x05;> 将立即数 0x05(1 byte) 复制到寄存器 al
R 表示寄存器(register)

间接寻址

就是到内存里去寻找数据。

内存如何寻址?

通过 signed-offset(base,index,scale) 来表示。
内存地址计算:
memory address = scale * index + base + signed-offset

举例说明

mov (%esi,%ebx,4), %edx
Move the 4 bytes of data at address esi+ 4 * ebx into edx.
%edx = 4 * %ebx + %esi
至此,如果将 scale = 8, 那就是 C 语言中的 long 型数据,如果同时递增 %ebx,那就是依次访问数组元素了。

register to memory (指针)

movl %eax, -4(%ebp)
表示为: mem[R[ebp]-4] = R[eax];
将寄存器 eax 里面的值复制到寄存器 ebp 的值减去 4 指向的内存地址处(也就是 R[ebp] -4 的值是一个内存地址).
通过寄存器指向了内存地址, 是不是很熟悉的指针啊, 对, 就是指针。 C 语言的指针就是这么玩的啊!

memory to register

movl -4(%ebp), %eax
%eax 表示为: R[eax] = mem[R[ebp] -4];
将寄存器 esp 的值减去 4 的值指向的内存地址处存放的值, 复制到寄存器 eax

代码分析

int main(){
    int i = 10;
    int *pi = &i;
    int ii = *pi;

    char c = 'z';
    char *pc = &c;
    char cc = *pc;

    long l = 1000000000L;
    long *pl = &l;
    long ll = *pl;

    return 0;

}
图解分析
C 代码和汇编对照

在这里插入图片描述

汇编代码分析

在这里插入图片描述

  1. 执行完12 这两个汇编指令后,假定 %rsp = %rbp = 1024(内存地址)。
  2. 汇编第 4 行:movl $10, -52(%rbp) , 可以从上图中看到 -52 内存地址处被赋值为 10,占据 4Bytes。movl 表示操作的是 32bit 的整数。这和 C 代码中第 6 行 int i = 10 保持一致。
  3. 汇编第 5 行: leaq -52(%rbp), %rax, 表示的是将 %rbp - 52 的内存地址,复制到 rax。因为使用的编译器是 x86-64gcc 10.2,是 64bits 的汇编代码,内存地址是 64bits。此时也就是 C 代码中,变量 i 的地址复制给 rax。
  4. 汇编第 6 行:movq %rax, -8(%rbp), 将此时 rax 复制到内存地址 %rbp - 8 的内存地址处。至此,完成了 C代码中第 7 行 int *pi = &i
  5. 汇编第 7 行:movq -8(%rbp),%rax,将 %rbp - 8 的内存地址处的值()指针(&i),复制到 rax。
  6. 汇编第 8 行: movl (%rax), %eax, 将 %rax 指向的值(i) 复制到 eax。可以看到此时使用的是 eax,也就是 32bits,正是 C 语言中 int 型数据。
  7. 汇编第 9 行: movl %eax, -12(%rbp), 将此时 eax 的值(i) 复制到 %rbp - 12 的内存地址处。至此,完成了 C 代码中第 8 行 int ii = *pi
  8. 其他的 char 和 long 类型,同理。

References

  1. 计算机怎么知道指针指向的具体类型?
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: forward x指针向前是指将指针x指向的地址向前移动。 在计算机编程中,指针一个变量,它保存的是另一个变量的地址。指针可以通过加减操作来改变指向的位置,这样就可以实现对内存中不同位置的访问和操作。 当我们说"forward x指针向前"时,意味着我们想要将指针x所指向的地址向前移动。具体移动的距离取决于所涉及的数据类型指针的定义。例如,如果x是一个指向整数的指针,那么向前移动x指针就表示将其指向的地址减小一个整数大小。 向前移动指针可以有多种用途。例如,在访问数组时,可以通过向前移动指针来遍历数组的元素。通过递增指针,我们可以按顺序访问数组中的元素,从第一个元素直到最后一个元素。 此外,向前移动指针还可以用于字符串处理。通过移动指针,我们可以遍历字符串中的每个字符,或者在字符串中查找特定的字符或子串。 总结来说,"forward x指针向前"是指将指针x所指向的地址向前移动,可以用于数组遍历、字符串处理等场景中对内存地址的操作和访问。 ### 回答2: forward x指针向前是指将指针x所指向的位置向前移动。在计算机编程中,指针一个变量,用于存储另一个变量的内存地址。通过使用指针,我们可以间接地访问和修改所指向的变量。 将指针向前移动意味着将其指向的位置向前偏移一定的距离,使其指向更远的内存位置。通过这种方式,我们可以在处理数据结构、数组或者其他需要遍历的数据序列时,轻松地移动指针来访问不同的元素。 在C或C++等编程语言中,可以使用指针算术运算来实现指针的前移。比如,对于一个指向int类型变量的指针ptr,可以通过执行ptr++来使指针向前移动一个单位。这样,ptr将指向一个int类型的位置。 指针向前的应用非常广泛。例如,在遍历数组时,可以使用指针来代替数组下标,通过不断将指针向前移动,来依次访问数组的元素。这种做法通常比使用下标更高效,因为指针的访问速度更快。 总之,将指针向前移动是一种在编程中常用的操作,它允许我们灵活地遍历和访问数据结构,提高程序的效率。通过掌握指针的使用和指针算术运算,我们可以更加灵活地操作内存和数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值