君子谬 发表于 2016-12-1 11:08

[谬]C语言指针的底层汇编实现原理

指针的赋值过程与指针类型的真相int指针:int gi;int *p;p = &gi;00EF166E C7 05 3C 91 EF 00 38 91 EF 00mov         dword ptr ds:,0EF9138h
*p = 12;00EF1678 A1 3C 91 EF 00                           mov         eax,dword ptr ds: 00EF167D C7 00 0C 00 00 00                      mov         dword ptr ,0Ch
注释:p = &gi;mov       dword ptr ds:,0EF9138h       将gi的地址0EF9138h放入00EF913Ch所指向的地址中保存 *p = 12;mov          eax,dword ptr ds:[00EF913Ch ]               将00EF913Ch所存储的地址,也就是gi的地址0EF9138h放入eax中.mov          dword ptr ,0Ch                                    将0ch放入eax所存储的地址中,也就是把0ch放在了gi所代表的地址中,dword也就代表了向eax中写入4字节数据


short型指针:
short gi;short *p;p = &gi;0034166E C7 05 3C 91 34 00 38 91 34 00 mov         dword ptr ds:,349138h *p = 12;00341678 B8 0C 00 00 00                                          mov         eax,0Ch 0034167D 8B 0D 3C 91 34 00                                 mov         ecx,dword ptr ds: 00341683 66 89 01                                                      mov         word ptr ,ax 注释:p = &gi; mov         dword ptr ds:,349138h         将gi的地址0EF9138h放入00EF913Ch所指向的地址中保存 *p = 12;mov         eax,0Ch                                                      将0Ch放入eax中,由于eax是4字节,所以0ch放到了eax的低2字节,ax中mov         ecx,dword ptr ds:                  将p所存储的地址,也就是gi的地址放入ecx中.mov         word ptr ,ax                                          将ax所存储的内容写入到ecx所指向的地址,也就是gi的地址,.word说明将向gi的地址写入2字节数据
char型指针:char gi;char *p; p = &gi;00CC166E C7 05 3C 91 CC 00 38 91 CC 00 mov         dword ptr ds:,0CC9138h *p = 12;00CC1678 A1 3C 91 CC 00                                           mov         eax,dword ptr ds: 00CC167D C6 00 0C                                                      mov         byte ptr ,0Ch
注释: p = &gi; mov         dword ptr ds:,0CC9138h      将gi的地址0EF9138h放入00EF913Ch所指向的地址中保存
*p = 12; mov         eax,dword ptr ds:                   将00EF913Ch所存储的地址,也就是gi的地址0EF9138h放入eax中.     mov         byte ptr ,0Ch                                           将0ch放入eax所存储的地址中,也就是把0ch放在了gi所代表的地址中,byte 也就代表了向eax所存储的地址中写入1字节数据
总结:   C语言指针包含两方面信息,一个是地址,存放在指针变量中,另一个是类型信息,决定了读写的长度,没有存储在指针变量中,位于指针读写过程所使用的mov指令中,不同的指针类型对应着读写的字节数.这也间接解释了指针为什么+-1不是+-1个字节,而是加减长度是指针类型的字节数,void类型的指针之所以无法加减,就是因为它没有类型信息,无法确定加减的长度,代表的仅仅是一块内存地址.
指针类型强制转换/****************************************************************/程序:int i;int * pi;short * ps;char * pc;int main(){                pi = &i;                ps = ( short *)&i;                pc = ( char *)&i;                *pi = 0x1234;                *ps = 0x1234;                *pc = 0x12;}/***************************************************************/
反汇编:
pi = &i;00941A8E C7 05 E0 94 94 00 DC 94 94 00 mov         dword ptr ds:,9494DCh ps = (short *)&i;00941A98 C7 05 E4 94 94 00 DC 94 94 00 mov         dword ptr ds:,9494DCh pc = (char *)&i;00941AA2 C7 05 E8 94 94 00 DC 94 94 00 mov          dword ptr ds:,9494DCh *pi = 0x1234;
注释:在把i赋值其他指针变量的过程中,强制转换并没有生成任何指令,可见,强制转换并不是在这里产生效果的
00941AAC A1 E0 94 94 00                                          mov         eax,dword ptr ds: 00941AB1 C7 00 34 12 00 00                                        mov         dword ptr ,1234h *ps = 0x1234;00941AB7 B8 34 12 00 00                                              mov         eax,1234h 00941ABC 8B 0D E4 94 94 00                                       mov         ecx,dword ptr ds: 00941AC2 66 89 01                                                         mov         word ptr ,ax *pc = 0x12;00941AC5 A1 E8 94 94 00                                             mov         eax,dword ptr ds: 00941ACA C6 00 12                                                       mov         byte ptr ,12h
注释: 可以看出,在这里,写入的字节数发生了变化,所以,强制转换的效果不在转换过程中体现,而是体现在转换后去访问内存时的指令中
注释2:如果转换后指针指向的数据类型大小小于原来的数据类型大小,那么用该转换后的指针访问就不会越过原数据的内存,是安全的,否则危险,要越界
/*****************************************************/程序:#include<stdio.h>
int main(){                int * pi;                short si = 12;                pi = ( int *)&si;                printf( "%d,%x", *pi, *pi);}/*****************************************************/
注释:正常情况下这段程序应该输入的是12,0c但是实际上的运行结果是-859045876,cccc000c这是由于将si的地址强制转换为int *类型,然后赋值给pi;那么pi会访问4字节,这时越界了,将si后的2字节纳入了范围,即是cc cc,他们和0c 00合在一起正好与结果吻合这就是违反了强制转换的原则,越界了

A学习的小菜鸟 发表于 2017-8-14 17:00

现在终于搞清楚从语言为什么是底层语言了,它与汇编有着很多的联系,这样可以更加清楚的理解底层的原理和认识,谢谢楼主的解答了啊

小可爱~ 发表于 2016-12-1 11:44

沙发躺着舒服,讲的不错, 给个评分

xiaodouble 发表于 2016-12-1 11:53

谢谢分享 有空可以看看

吾爱丨破解 发表于 2016-12-1 12:06

????ケ??????

mingo 发表于 2016-12-1 12:36

还不错!

JIESHAO??? 发表于 2016-12-1 12:46

感谢分享

ytw6176 发表于 2016-12-1 12:48

晕针。。   

pcx127 发表于 2016-12-1 12:53

这个对c指针很有用。。

dongdon923 发表于 2016-12-1 13:23

感谢分享

牵手的幸福~ 发表于 2016-12-1 19:11

了解了!谢谢
页: [1] 2
查看完整版本: [谬]C语言指针的底层汇编实现原理