从汇编语言角度辨析char*str="abc"和char str[]="abc"

所以说想要从根本上理解这种语言上的trick就要直接看他的汇编代码,对着经验和现象猜来猜去就如同盲人摸象。

    char*str="abc";
01092BFE  mov         dword ptr [str],109CC70h  
    char strr[]="abc";
01092C05  mov         eax,dword ptr ds:[0109CC70h]  
01092C0A  mov         dword ptr [strr],eax  

“abc”是一个常量,常量是程序在编译的时候就确定好了的东西,它就跟代码一样,在进程地址空间中,常量区就在代码段的上边,这两个区域都是只读的(这两个区域真的是只读的,跟栈内const修饰的假常量可不一样),这个109CC70h就是处于常量区的一个地址,从他开始后边4个字节里存着abc\0。

我们可以看到char*str里存的就是这个常量区的地址,你想对它进行修改是不会被允许的,因为这段内存是只读的,你修改它会造成运行时错误。这里也有个疑问,到底是系统的那部分规定无法修改虚拟内存中某些地址的,我猜测是linux内核中表示进程的task_struct中管理虚拟内存各段的链表中的某个表示权限的flag,不过目前还没有去查证。

再看strr[]的赋值操作,很明显它只是把常量区的字符串值取出来放到寄存器,再由把寄存器中的值拷贝到栈内空间,我们修改的只是栈内的空间,合理合法。

猜你喜欢

转载自blog.csdn.net/qq_33113661/article/details/89192301
ABC