在汇编中看一维数组与二维数组

对于一对同样大小的二维数组和一维数组,
他们在汇编中都是在栈里尺寸相等的一段连续空间,除了入口地址之外,没有区别。
真正让他们产生区别的是代码中后续对各个数组进行的操作:
操作二维数组时,编译器自动将其指向的数据类型计算出来,然后翻译成对应的汇编代码进行操作。

比如对于int arr[4][10]来说:
arr[2]之所以能取到对应的arr[2][0]的地址,
是由于C的编译器让arr指向的数据类型为 int * 10 = 40字节,
arr[2]就等于(arr的地址 + 2*40)之后的地址。
C编译器直接把这个表达式翻译成汇编,汇编并不知道arr能偏移多少。

  1. 栈空间层面
    同样大小的一维、二维数组,在汇编里就是两段等大、连续的栈内存,只有基地址不同,无任何区别。
  2. 类型与偏移层面
    数组的类型信息(步长)只存在于编译期,汇编不存储任何类型、维度信息。
  3. 操作时的区别
    当你操作数组时,编译器根据类型算出偏移量,直接把计算规则写进汇编指令:
    • int arr[4][10] → 类型 int (*)[10] → 步长 40 字节
    • arr[2] → 编译器翻译为:arr 基地址 + 2*40
    • 最终得到 &arr[2][0]
  4. 核心真相汇编只负责执行地址计算,不知道偏移规则;规则是编译器在编译时根据类型定好的。

数组维度是给编译器看的,不是给汇编 / CPU 看的;编译器根据类型算偏移,汇编只认最终地址。

滚动至顶部