|
发表于 2015-11-20 17:08:23
|
显示全部楼层
楼上说得对, 你这个问题涉及到一点汇编知识,且听我细细讲来
先讲明白变量的初始化时,初始化的数值存放在哪
例如 int nNum = 1;
这个1是放在代码段中的,转成汇编指令就像下面
mov eax,1
mov nNum,eax
像mov eax,1这条指令就是将1放到eax这个寄存器中,这条指令中的1它是一种寻址方式,叫做立即数寻址,所谓的立即数寻址就是说,一条把数字放到寄存器的指令中,放入寄存器的数据不是存放在别的地址的内存中,而是就存放在指令中。
mov nNum,eax.这条指令就是把eax中的内容放到Nnum变量中,
不直接把mov nNum,1,是因为intel的工程师设计的CPU,不允许将一个内存地址中的内容复制到另一个内存地址中,nNum是个变量,变量实际上就是个内存地址的别名,而1其实也是内存地址,因为所有的数据都应该是存放在内存中的,只不过这个1存放的内存地址是比较独特,不用根据内存地址寻址到内存中,将数据提取出来,而是早已经将数据放到代码中。
说这个是因为要说double类型的变量是怎么进行初始化的
比如 double dNum = 1.1;
转换成汇编就是
movups xmm0,dqword ptr ds:[0x12345678]
这条指令的意思大概就是将内存地址0x12345678处的数据放到xmm0寄存器中,而dqword ptr 是指明取出数据的大小,byte 是1个字节,word是2个字节,dword是double word 4个字节,qword是8个字节,dqword是16个字节,
这个xmm0也是个寄存器,和eax不一样的是,eax只能存4个字节的整数,xmm0是存储16个字节(128位)的浮点型数据的,浮点数的存储跟整形的存储不一样,需要用特殊的指令去操作浮点型寄存器去存放,而且浮点型数据也不能直接movups xmm0,1.1,为什么,你看,1能放在代码中,是因为可以表示出来,但是1.1是没有办法在代码中表示出来的,具体原因是因为一条机器码,最大的长度只不过16个字节,而一个浮点数就16个字节了,所以只能放到内存中,在放入内存中时,也是有讲究的需要将1.1转换成一个很大的浮点数,怎么转换就说不清了,反正1.1大概能转成这样的十六进制数:9A9999999999F13F0000000000000000 ,
然后再进行计算的时候,需要将这串长长的表示1.1的小数放到xmm0中,再用专门的指令进行算,然后才得到结果。
这是编译器自动根据变量的类型来决定使用哪种汇编指令的,所以你int型,编译器会用普普通通的指令去处理,对于浮点型,是需要特殊寄存器,特殊指令才能狗进行计算的,
像int型这种小渣渣的数据类型,它们的四则运算只能通过普通的寄存器和普通的指令进行计算,普通的寄存器和普通的指令当然得不到浮点型的结果,要不然还设计一套专门用来处理浮点型的寄存器和指令干什么呢 |
|