Reference description> 【Author: Zhang Pei ]【Original: Http://blog.csdn.net/blog_index]
During the National Day holiday, I saw the sample project in wdk 8.1. It encountered a very interesting problem. It was related to the basic pointer usage, which is specially mentioned here. See the following code in the wdk8.1 msplot Project (simplified by me), three lines, and a subtraction operation. The sample value in the annotation, the expected result should be 0x10, but an overflow warning is returned unexpectedly:
/* Struct _ plotgpc *//*{*//*//... * // * lpvoid pdata; * // *}; */lpbyte * pbyte = pplotgpc-> pdata; // pbyte: 0x0040fa30pbyte-= (ulong_ptr) pplotgpc; // pplotgpc: 0x0040fa20pplotgpc-> pdata = pbyte; // result: 0xff3d11b0
Pdata originally points to a piece of memory next to the struct, which is an absolute address. Now we need to change pdata to a relative address, that is, the offset relative to the struct header. You only need to subtract the starting address of the struct from the current value. However, the results are quite surprising, and they always get an overflow number. The following is an example:
Pplotgpc: 0x0040fa20pplotgpc-> pdata: 0x0040fa30 result: 0x0040fa30-0x0040fa20 = 0xff3d11b0
This result surprised me if the CPU is broken. But after reading the assembly, I know the reason.
00ff107d mov ECx, dword ptr [pplotgpc] 00ff1080 SHL ECx, 2 // multiply by 4, to shift left 2 implement 00ff1083 mov edX, dword ptr [ebp-0Ch] 00ff1086 sub edX, ecx00ff1088 mov dword ptr [ebp-0Ch], EDX
In this subtraction operation, the subtraction is first multiplied by 4 and then subtracted:
0x0040fa30 - (0x0040fa20×4)
What is going on? From where is the extra 4? See the definition of pbyte:
LPBYTE *pByte;
Its type is (lpbyte *), and lpbyte is the macro definition of (byte *), so it can be converted:
BYTE** pByte;
Therefore, this is the subtraction operation of pointer variables. The pointer type is (byte *). All those who have learned the C language understand that the addition and subtraction of pointers is a multiple of the addition and subtraction of their type size. Because its type is still a pointer (**), the Type length is either 4 or 8 Based on the hardware platform. The compiled target object is Win32 and the pointer length is 4. This is why the assembly code is multiplied by 4.
After you think about it, it seems like a pen mistake. The solution is close to a joke. You just need to remove:
LPBYTE *pByte; ==> LPBYTE pByte;
Once a "*" is removed, the pointer type is changed to byte, and the length of the byte type is 1.
An asterisk is added"