2015春季腾讯实习在线测试题之求int型字节长度,不准用sizeof

不使用sizeof,求某机器平台的int型整数位数(16,32,64)

思路,将整数变成字符串处理,并且在内存的末尾填零,即字符串结束符。

如 0x0012,0x00123456,0x00123456789ABCDE分别对应16,32,64位数; 小端机

代码

#include <stdio.h>

#include <string.h>

int main(int argc , char *argv[])

{

       intn16 = 0x0012;

       /*

              此处用于填充内存防止出现内存连续

              如, 32位机器上。 

*/

       intnIntNop1 = 0; 

       intnIntNop2 = 0;

       intn32 = 0x00123456;

       intnIntNop3 = 0;

       intnIntNop4 = 0;

       intn64 = 0x00123456789ABCDE;

       intnInt16 = strlen((char *)&n16);

 

       intnInt32 = strlen((char *)&n32);

 

       intnInt64 = strlen((char *)&n64);

       if(1== nInt16 && 2 == nInt32 && 2 == nInt64)

       {

              printf("16Bits\n");

       }

       if(1== nInt16 && 3 == nInt32 && 4 == nInt64)

       {

              printf("32Bits\n");

       }

       if(1== nInt16 && 3 == nInt32 && 7 == nInt64)

       {

              printf("64Bits\n");

       }

       return0;

}

 

反汇编分析:

5:       int n16 = 0x0012;

00401028  mov         dword ptr [ebp-4],12h

6:       int nIntNop1 = 0;

0040102F   mov         dword ptr [ebp-8],0

7:       int nIntNop2 = 0;

00401036  mov         dword ptr [ebp-0Ch],0

8:       int n32 = 0x00123456;

0040103D  mov         dword ptr [ebp-10h],123456h

9:       int nIntNop3 = 0;

00401044  mov         dword ptr [ebp-14h],0

10:      int nIntNop4 = 0;

0040104B  mov         dword ptr [ebp-18h],0

11:      int n64 = 0x00123456789ABCDE;

00401052  mov         dword ptr [ebp-1Ch],789ABCDEh

12:      int nInt16 = strlen((char *)&n16);

00401059  lea         eax,[ebp-4]

0040105C   push        eax

0040105D  call        strlen (004011b0)

00401062  add         esp,4

00401065  mov         dword ptr[ebp-20h],eax

13:

14:      int nInt32 = strlen((char *)&n32);

00401068  lea         ecx,[ebp-10h]

0040106B  push        ecx

0040106C   call        strlen (004011b0)

00401071  add         esp,4

00401074  mov         dword ptr[ebp-24h],eax

15:

16:      int nInt64 = strlen((char *)&n64);

00401077  lea         edx,[ebp-1Ch]

0040107A   push        edx

0040107B  call        strlen (004011b0)

00401080  add         esp,4

00401083  mov         dword ptr[ebp-28h],eax

17:      if(1 == nInt16 && 2 == nInt32 && 2 == nInt64)

00401086  cmp         dword ptr [ebp-20h],1

0040108A   jne         main+95h (004010a5)

0040108C   cmp         dword ptr [ebp-24h],2

00401090  jne         main+95h (004010a5)

00401092  cmp         dword ptr [ebp-28h],2

00401096  jne         main+95h (004010a5)

18:      {

19:           printf("16 Bits\n");

00401098  push        offset string "16Bits\n" (00422034)

0040109D  call        printf (00401130)

004010A2   add         esp,4

20:      }

21:      if(1 == nInt16 && 3 == nInt32 && 4 == nInt64)

004010A5   cmp         dword ptr [ebp-20h],1

004010A9   jne         main+0B4h (004010c4)

004010AB  cmp         dword ptr [ebp-24h],3

004010AF  jne         main+0B4h (004010c4)

004010B1  cmp         dword ptr [ebp-28h],4

004010B5  jne         main+0B4h (004010c4)

22:      {

23:           printf("32 Bits\n");

004010B7  push        offset string "32Bits\n" (00422028)

004010BC  call        printf (00401130)

004010C1   add         esp,4

24:      }

25:      if(1 == nInt16 && 3 == nInt32 && 7 == nInt64)

004010C4   cmp         dword ptr [ebp-20h],1

004010C8   jne         main+0D3h (004010e3)

004010CA  cmp         dword ptr [ebp-24h],3

004010CE  jne         main+0D3h (004010e3)

004010D0  cmp         dword ptr [ebp-28h],7

004010D4  jne         main+0D3h (004010e3)

26:      {

27:           printf("64 Bits\n");

004010D6  push        offset string "64Bits\n" (0042201c)

004010DB  call        printf (00401130)

004010E0  add         esp,4

28:      }

29:      return 0;

004010E3  xor         eax,eax

30:  }

004010E5  pop         edi

004010E6  pop         esi

004010E7  pop         ebx

004010E8  add         esp,68h

004010EB  cmp         ebp,esp

004010ED  call        __chkesp (00401230)

004010F2   mov         esp,ebp

004010F4   pop         ebp

004010F5   ret

 

Vc6.0下  32位平台

初始寄存器:执行5:xxx 语句之前

EAX = CCCCCCCC EBX = 7EFDE000

 ECX= 00000000 EDX = 002A1810

 ESI= 00000000 EDI = 0018FF48

 EIP= 00401028 ESP = 0018FED4

 EBP= 0018FF48 EFL = 00000202

初始内存

0018FEFB CC CC CC CC CC CC CC  烫烫烫.

0018FF02 CC CC CC CC CC CC CC  烫烫烫.

0018FF09 CC CC CC CC CC CC CC  烫烫烫.

0018FF10 CC CC CC CC CC CC CC  烫烫烫.

0018FF17 CC CC CC CC CC CC CC  烫烫烫.

0018FF1E CC CC CC CC CC CC CC  烫烫烫.

0018FF25 CC CC CC CC CC CC CC  烫烫烫.

0018FF2C  CC CC CC CC CC CC CC  烫烫烫.

0018FF33 CC CC CC CC CC CC CC  烫烫烫.

0018FF3A  CC CC CC CC CC CC CC  烫烫烫.

0018FF41 CC CC CC CC CC CC CC  烫烫烫.

0018FF48 88 FF 18 00 59 13 40  ....Y.@

 

之后  内存

 

0018FEFB CC CC CC CC CC CC CC  烫烫烫.

0018FF02 CC CC CC CC CC CC CC  烫烫烫.

0018FF09 CC CC CC CC CC CC CC  烫烫烫.

0018FF10 CC CC CC CC CC CC CC  烫烫烫.

0018FF17 CC CC CC CC CC CC CC  烫烫烫.

0018FF1E CC CC 04 00 00 00 03  烫.....  4是因为那个DEBC9A78的缘故最后不是0

0018FF25 00 00 00 0100 00 00  .......   此处分别是 1 和3 即是32位下的

0018FF2C  DE BC 9A 7800 00 00  藜歺...   那个没有放下的整数0x00123456789ABCDE

0018FF33 00 00 00 00 00 56 34  .....V4         截取了末位的八个字节

0018FF3A  12 00 00 00 00 00 00 .......           32位整数0x00123456

0018FF41 00 00 00 12 00 00 00  .......

0018FF48 88 FF 18 00 59 13 40  ....Y.@

收尾之后

0018FEED CC CC CC CC CC CC CC  烫烫烫.

0018FEF4 CC CC CC CC CC CC CC  烫烫烫.

0018FEFB CC CC CC CC CC CC CC  烫烫烫.

0018FF02 CC CC CC CC CC CC CC  烫烫烫.

0018FF09 CC CC CC CC CC CC CC  烫烫烫.

0018FF10 CC CC CC CC CC CC CC  烫烫烫.

0018FF17 CC CC CC CC CC CC CC  烫烫烫.

0018FF1E CC CC 04 00 00 00 03  烫.....

0018FF25 00 00 00 01 00 00 00  .......

0018FF2C  DE BC 9A78 00 00 00  藜歺...

0018FF33 00 00 00 00 00 56 34  .....V4

0018FF3A  12 00 00 00 00 00 00  .......

0018FF41 00 00 00 F2 10 40 00  .....@.  004010ED call __chkesp (00401230) 之后改变了值,估计是已经回收了内存,有待日后研究。

0018FF48 88 FF 18 00 59 13 40  ....Y.@

 

 

原来的错去程序

#include <stdio.h>

#include <string.h>

int main(int argc , char *argv[])

{

       intn16 = 0x0012;

       intn32 = 0x00123456;

       intn64 = 0x00123456789ABCDE;

       intnInt16 = strlen((char *)&n16);

 

       intnInt32 = strlen((char *)&n32);

 

       intnInt64 = strlen((char *)&n64);

       if(1== nInt16)

       {

              printf("16Bits\n");

       }

       if(3== nInt32)

       {

              printf("32Bits\n");

       }

       if(7== nInt64)

       {

              printf("64Bits\n");

       }

       return0;

}

初始执行前

EAX = CCCCCCCC EBX = 7EFDE000

 ECX= 00000000 EDX = 004F1810

 ESI= 00000000 EDI = 0018FF48

 EIP= 00401028 ESP = 0018FEE4

 EBP= 0018FF48 EFL = 00000206

 

0018FEFB CC CC CC CC CC CC CC  烫烫烫.

0018FF02 CC CC CC CC CC CC CC  烫烫烫.

0018FF09 CC CC CC CC CC CC CC  烫烫烫.

0018FF10 CC CC CC CC CC CC CC  烫烫烫.

0018FF17 CC CC CC CC CC CC CC  烫烫烫.

0018FF1E CC CC CC CC CC CC CC  烫烫烫.

0018FF25 CC CC CC CC CC CC CC  烫烫烫.

0018FF2C  CC CC CC CC CC CC CC  烫烫烫.

0018FF33 CC CC CC CC CC CC CC  烫烫烫.

0018FF3A  CC CC CC CC CC CC CC  烫烫烫.

0018FF41 CC CC CC CC CC CC CC  烫烫烫.

0018FF48 88 FF 18 00 39 13 40  ....9.@

 

执行后

0018FF25 CC CC CC CC CC CC CC  烫烫烫.

0018FF2C  CC CC CC CC 07 00 00  烫烫...

0018FF33 00 03 00 00 00 01 00  .......

0018FF3A  00 00 DE BC 9A 7856  ..藜歺V 执行n64 和 n32赋值之后  恍然大悟。。

0018FF41 34 12 00 12 00 00 00  4......     对内存把握不够。。果断牺牲。

0018FF48 88 FF 18 00 39 13 40  ....9.@

 

若是64位机器则 包含两个0填充

目测是这样的

DE BC 9A78 56 34 12 00

00 00 00 00 00 00 0000填充的0

00 00 00 00 00 00 00 00

56 34 12 00 00 00 00 00

00 00 00 00 0000 00 00

00 00 00 00 00 0000 00

12 00 00 00 0000 00 00

 

若是16位机器  目测是这样的

DE BC

00 00

00 00

56 34

00 00

00 00

12 00

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值