汇编指令中是没有数组概念的,数组是高级语言中抽象出来的一个一块内存数据的概念,它有数据类型,也有自己的长度,那如何用简单的汇编指令实现抽象的数组功能的?
老规矩,先上一段简单的一看就懂的C语言代码:
#include<stdio.h>
int main(){
int arr[5] = {1, 2, 3, 4, 5};
arr[2] = 22;
arr[4] = 44;
return 0;
}
下面是上述代码对应的汇编代码:
subq $32, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $1, -32(%rbp)
movl $2, -28(%rbp)
movl $3, -24(%rbp)
movl $4, -20(%rbp)
movl $5, -16(%rbp)
movl $22, -24(%rbp)
movl $44, -16(%rbp)
movl $0, %eax
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
je .L3
call __stack_chk_fail@PLT
.L3:
leave
上面是一维数组,下面是二维数组:
#include<stdio.h>
int main(){
int arr[2][5] = {{1, 2, 3, 4, 5},
{6,7,8,9,10}};
arr[0][2] = 222;
arr[1][4] = 444;
return 0;
}
********************** 汇编程序 ************************
subq $48, %rsp
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $1, -48(%rbp)
movl $2, -44(%rbp)
movl $3, -40(%rbp)
movl $4, -36(%rbp)
movl $5, -32(%rbp)
movl $6, -28(%rbp)
movl $7, -24(%rbp)
movl $8, -20(%rbp)
movl $9, -16(%rbp)
movl $10, -12(%rbp)
movl $222, -40(%rbp)
movl $444, -12(%rbp)
movl $0, %eax
movq -8(%rbp), %rdx
xorq %fs:40, %rdx
je .L3
call __stack_chk_fail@PLT
.L3:
leave
数组操作没什么好说的,总的来说就是直接分配了好几个int,而当你用指针下标去读取或修改数组内的某个元素时,比如这里的arr[4] = 44,这里是怎么找到arr[4]这个元素的?实际上是编译器计算的,编译器把arr[4]对应的关于栈帧rbp的相对地址算出来了,然后提供一条指令直接给这个内存单元赋值44,也就是汇编代码里的movl $44, -16(%rbp),一切都是编译器计算好了的。
因此,所谓数组概念,其实就是编译器提前算好的地址,并将这块内存地址当成这个数组,以后操作数组,就利用简单的汇编指令操作这块内存就是了。那么,其它复杂的数组操作时怎么做到的呢?我们会在后面指针部分做详细揭晓。