Let me tell you why you are here. You have come because you know something. What you know you can't explain but you feel it. You've felt it your whole life, felt that something is wrong with the world. You don't know what, but it's there like a splinter in your mind, driving you mad. It is this feeling that brought you to me. Do you know what I'm talking about?
10/31/2007
LNK2028, LNK2019 without extern "C"
I wrote a Win32 dll in VS2005 and a CLR-Console client, the CLR-Console client is the caller of Win32 dll. In the Win32 dll, using /TC compiler option to build it and using /clr option to build the CLR-Console client. The all things is fine, such as 'dllexport/dllimport', 'Additional Include Deirectories' and 'Additional Dependencies'. But I got LNK2028 unresolved token and LNK2019 unresolved external symbol, the reason is I forgot using the extern "C" to include all dllexport functions.
10/23/2007
Reversing string in C
There is a example for reversing string in the Section 3.5 of K&R's 'The C Programming Language' . The example code look like this:
void reverse(char s[]) {
But the above code can be improved. There is 'Pointer Version':
void reverse(char *s) {
The *strrev* in C standard library implements the same functionality, but generally implements in assembly code.
void reverse(char s[]) {
char c;
int i, j;
for (i = 0, j = strlen(s) - 1; i < j; ++i, --j) {
}int i, j;
for (i = 0, j = strlen(s) - 1; i < j; ++i, --j) {
c = s[i], s[i] = s[j], s[j] = c;
}But the above code can be improved. There is 'Pointer Version':
void reverse(char *s) {
char *l = s;
char c;
while (*s++)
while (l < s) {
}char c;
while (*s++)
;
s -= 2;while (l < s) {
c = *l;
*l++ = *s;
*s-- = c;
}*l++ = *s;
*s-- = c;
The *strrev* in C standard library implements the same functionality, but generally implements in assembly code.
10/20/2007
Item not found: Could not find this item! on Vista
When u try to remove a directory under the Vista GUI, u'll get 'Item not found: Could not find this item'. Or, u'll get 'The system cannot find the file specified' under the Vista command prompt.
Try the following:
1. Open the command prompt.
2. Execute *dir /x* to display 8.3 file name
3. Execute *rd filename* the filename 8.3 format that u got it in step 2.
Try the following:
1. Open the command prompt.
2. Execute *dir /x* to display 8.3 file name
3. Execute *rd filename* the filename 8.3 format that u got it in step 2.
10/18/2007
The #end joke
I found a joke when I publish my blog through the gmail. Wrote a blog which includes a piece of C/C++ code. Within that, the *# e n d i f* C/C++ directive had been used. So after send my blog, I got truncated blog content, Ha.
Because, u can use the *# e n d* flag in ur gmail in order to indicate blogger to truncate the content after *# e n d* flag. It's a joke.
Because, u can use the *# e n d* flag in ur gmail in order to indicate blogger to truncate the content after *# e n d* flag. It's a joke.
Organize IA-32 machine code in C++ class
First, look the following code:
#include <iostream>
#pragma pack(push, 1)
class MachineCode {
public:
#pragma pack(pop, 1)
typedef void (__stdcall *ProcCall)(void);
class Adapter {
public:
Then, I use the following code to call X::DefProcCall function:
Adapter x;
x.Init (&Adapter::DefProcCall, &x);
ProcCall call = x.GetProcCaller();
call();
The all magic is at 'reinterpret_cast<ProcCall>(
#include <iostream>
#pragma pack(push, 1)
class MachineCode {
public:
unsigned char jmp_;
unsigned long proc_;
};#pragma pack(pop, 1)
typedef void (__stdcall *ProcCall)(void);
class Adapter {
public:
int Init(void* proc, void* pthis) {
ProcCall GetProcCaller(void) {
static void DefProcCall(void) {
private: thunk_.jmp_ = 0xE9;
thunk_.proc_ = (unsigned long)proc - ((unsigned long)pthis + sizeof(thunk_));
::FlushInstructionCache(::GetCurrentProcess(), pthis, sizeof(thunk_));
return (true);
}thunk_.proc_ = (unsigned long)proc - ((unsigned long)pthis + sizeof(thunk_));
::FlushInstructionCache(::GetCurrentProcess(), pthis, sizeof(thunk_));
return (true);
ProcCall GetProcCaller(void) {
return (reinterpret_cast<ProcCall>(&thunk_));
}static void DefProcCall(void) {
std::cout<<"in Adapter::DefProcCall.\n"<<std::endl;
}MachineCode thunk_;
};Then, I use the following code to call X::DefProcCall function:
Adapter x;
x.Init (&Adapter::DefProcCall, &x);
ProcCall call = x.GetProcCaller();
call();
The all magic is at 'reinterpret_cast<ProcCall>(
&thunk_)' in GetProcCaller member function of Adapter class and two data members in MachineCode class. Directly, generates such IA-32 code 'call dword ptr [function-address]' when C++ compiler meet 'call()' statement. Because of the function-address exactly is the address of the thunk_ which is the first data member of Adapter class. So the machine code in thunk_ has been executed.
The jmp_ data member of MachineCode class stores 0xE9 that is 'jmp' instruction in IA-32. And the proc_ data member stores relative address since the ending address of the thunk_ which in Adapter class. So whole MachineCode class generate such IA-32 code 'jmp address'.
The jmp_ data member of MachineCode class stores 0xE9 that is 'jmp' instruction in IA-32. And the proc_ data member stores relative address since the ending address of the thunk_ which in Adapter class. So whole MachineCode class generate such IA-32 code 'jmp address'.
10/16/2007
[] Operator in IA-32 assembly code
[] bracket operator means get the content of the memory location, u can treat [location] as addressing expression.
The following C code:
int i;
i = 0x1234;
can be translate to assembly code which looks like this:
mov dword ptr [i], 1234h
the dword ptr means the content of variable i occupied 4 bytes. It is required because of IA-32 is byte addressable. And above mov instruction does not know how much storage requires for storing immediate number 1234h.
The following C code:
int i;
i = 0x1234;
can be translate to assembly code which looks like this:
mov dword ptr [i], 1234h
the dword ptr means the content of variable i occupied 4 bytes. It is required because of IA-32 is byte addressable. And above mov instruction does not know how much storage requires for storing immediate number 1234h.
10/15/2007
Cannot install Microsoft Server 2003 SP2!
*update.inf*
1. net stop cryptsvc
2. ren %systemroot%\system32\catroot2 old-catroot2
3. net start cryptsvc
1. net stop cryptsvc
2. ren %systemroot%\system32\catroot2 old-catroot2
3. net start cryptsvc
10/14/2007
Manipulate bits in C
1. Definition:
const int FIRST = 1 << 0;
const int SECOND = 1 << 1;
const int THIRD = 1 << 2;
Why defines the bit flag like this? Oh, just for clarity.
2. Setting bit flag:
int flags = 0;
flags |= FIRST;
flags |= SECOND;
flags |= THIRD;
if (flags & FIRST) {
printf("FIRST bit has been set.\n");
} else if (flags & SECOND) {
printf("SECOND bit has been set.\n");
}
...
3. Clearing bit flag:
flags &= ~FIRST;
flags &= ~SECOND;
...
const int FIRST = 1 << 0;
const int SECOND = 1 << 1;
const int THIRD = 1 << 2;
Why defines the bit flag like this? Oh, just for clarity.
2. Setting bit flag:
int flags = 0;
flags |= FIRST;
flags |= SECOND;
flags |= THIRD;
if (flags & FIRST) {
printf("FIRST bit has been set.\n");
} else if (flags & SECOND) {
printf("SECOND bit has been set.\n");
}
...
3. Clearing bit flag:
flags &= ~FIRST;
flags &= ~SECOND;
...