Reputation: 9599
Check out this C code compiled with VC++ 2003/2005.
#include <stdio.h>
#include <windows.h>
void WINAPI SomeFunction(WORD a, WORD b)
{
printf("%d + %d = %d\n", a, b, a + b);
}
int main()
{
__asm {
MOV EAX, 5
MOV EBX, 6
PUSH EBX
PUSH EAX
CALL SomeFunction
}
return 0;
}
In this ASM code, I'm passing two DWORD
(4 bytes) arguments (by default as far as I know) to the SomeFunction()
function that expects two WORD
(2 bytes) arguments, and works perfectly (outputs 5 + 6 = 11
).
1) Why this works?
Knowing that the function takes two WORD
arguments, I'll do this:
__asm {
MOV WORD PTR [EAX], 5
MOV WORD PTR [EBX], 6
PUSH EBX
PUSH EAX
CALL SomeFunction
}
While debugging it throws a Segmentation fault error.
2) Why this doesn't work?
Thanks in advance!
Upvotes: 2
Views: 320
Reputation: 98348
The first one works because the Win32 ABI says that any argument with size less or equal 4 bytes is passed as 4 bytes, padding if necessary. So 16-bit words are actually passed as 32 bits. And that's what you are doing.
The second one does not work because it does a different thing:
MOV WORD PTR [EAX], 5
That line moves 5
into the 16-bit word starting at the memory location pointed to by EAX
. But EAX
is not loaded previously with a valid memory address. Moreover you are then pushing the pointer (a WORD*
?).
In order to pass a 16-bit value in the stack you could use:
MOV AX, 5
MOV BX, 6
PUSH AX
PUSH BX
But that goes agains the Win32 ABI, as the stack is always 32-bit aligned.
Interestingly that will work if you pass this structure by value (untested):
struct WW
{
WORD a, b;
};
void WINAPI SomeFunction(WW w)
{
printf("%d + %d = %d\n", w.a, w.b, w.a + w.b);
}
int main()
{
__asm {
MOV BX, 6 // the parameters are reversed, methinks
MOV AX, 5
PUSH BX
PUSH AX
CALL SomeFunction
}
return 0;
}
That's because the fields of the structure are packed in 4 bytes (sizeof(WW)==4
), so that's what is copied to the stack.
Naturally, playing with 16-bit registers is not fun. It is probably better to do:
MOV EAX 0x00060005
PUSH EAX
And copy the whole 32-bit struct in one go.
Upvotes: 3