字面量、变量的存储

3.1.2.1.4 字面量、变量的存储

我们先想一下C程序是如何读写字面量、变量的。

#include 
int main()
{
    char *name = "pangudashu";

    printf("%s\n", name);
    return 0;
}

我们知道指针name分配在栈上,而"pangudashu"分配在常量区,那么"name"变量名分配在哪呢?

实际上C里面是不会存变量名称的,编译的过程会将变量名替换为偏移量表示:ebp - 偏移量esp + 偏移量,将上面的代码转为汇编:

.LC0:
    .string "pangudashu"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movq    $.LC0, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rax, %rdi
    call    puts
    movl    $0, %eax
    leave

可以看到movq $.LC0, -8(%rbp),而-8(%rbp)就是name变量。

虽然PHP代码不会直接编译为机器码,但编译、执行的设计跟C程序是一致的,也有常量区、变量也通过偏移量访问、也有虚拟的执行栈。

php vs c

在编译时就可确定且不会改变的量称为字面量,也称作常量(IS_CONST),这些值在编译阶段就已经分配zval,保存在zend_op_array->literals数组中(对应c程序的常量存储区),访问时通过_zend_op_array->literals + 偏移量读取,举个例子:

$a = 56;
$b = "hello";

56通过(zval*)(_zend_op_array->literals + 0)取到,hello通过(zval*)(_zend_op_array->literals + 16)取到,具体变量的读写操作将在执行阶段详细分析,这里只分析编译阶段的操作。

联系我们

邮箱 626512443@qq.com
电话 18611320371(微信)
QQ群 235681453

Copyright © 2015-2024

备案号:京ICP备15003423号-3