i'm trying to write a procedure in asm that will be called in c.
this procedure takes a pointer to a structure and then modifies its fields.
why does this code give me a runtime error?
function PROC STDCALL arg:DWORD
push ebx
mov ebx, [arg]
mov [ebx].MYSTRUCT.val, 3
pop ebx
ret 4
function ENDP
and why does this one work, but it actually suffers from the invertion of bytes representation mechanism,
so actually, in my c code the arg.val is 0.
function PROC STDCALL arg:DWORD
push ebx
mov ebx, [esp + sizeof DWORD * 2]
assume ebx:ptr MYSTRUCT
mov [ebx].val, 4
pop ebx
function ENDP
you probably pass an invalid pointer to the procedure. The shown code is right.
The second example doesn't have a RET in it.
What compiler/version of C are you using? How are you defining the "extern" function? And how are you calling the function?
Microsoft (R) Macro Assembler Version 10.00.30319.01(ml.exe),
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86 (cl.exe),
and migw gcc under windows
aloha_arts, please use the REPLY button instead of editing you post when you've got a answer :U
Also the
mov ebx, [esp + sizeof DWORD * 2]
is false. it must be
mov ebx,[esp+3*4]
I'd be cautious with how you are accessing the parameters, MASM 6.15 is building prologue/epilogue code which you are not accounting for. I'd have to try it with 10.0, and personally I prefer the CDECL method over STDCALL.
test7a.asm (ml -c -coff -Fl test7a.asm)
.386
.MODEL FLAT, C
.CODE
MYSTRUCT STRUCT
str1 BYTE 10 dup(?)
str2 BYTE 10 dup(?)
val DWORD ?
MYSTRUCT ENDS
Func1 PROC STDCALL arg:DWORD
push ebx
mov ebx,arg
mov [ebx].MYSTRUCT.val,1234h
pop ebx
ret
Func1 ENDP
Func2 PROC C arg:DWORD
push ebx
mov ebx,arg
mov [ebx].MYSTRUCT.val,5678h
pop ebx
ret
Func2 ENDP
function PROC STDCALL arg:DWORD
push ebx
mov ebx, [esp + sizeof DWORD * 2]
assume ebx:ptr MYSTRUCT
mov [ebx].val, 4
pop ebx
ret
function ENDP
END
Disassembly
00000000 _Func1@4:
00000000 55 push ebp
00000001 8BEC mov ebp,esp
00000003 53 push ebx
00000004 8B5D08 mov ebx,[ebp+8]
00000007 C7431434120000 mov dword ptr [ebx+14h],1234h
0000000E 5B pop ebx
0000000F C9 leave
00000010 C20400 ret 4
00000013 _Func2:
00000013 55 push ebp
00000014 8BEC mov ebp,esp
00000016 53 push ebx
00000017 8B5D08 mov ebx,[ebp+8]
0000001A C7431478560000 mov dword ptr [ebx+14h],5678h
00000021 5B pop ebx
00000022 C9 leave
00000023 C3 ret
00000024 _function@4:
00000024 55 push ebp
00000025 8BEC mov ebp,esp
00000027 53 push ebx
00000028 8B5C2408 mov ebx,[esp+8]
0000002C C7431404000000 mov dword ptr [ebx+14h],4
00000033 5B pop ebx
00000034 C9 leave
00000035 C20400 ret 4
Using Microsoft C 15.00 (cl test7c.c test7a.obj)
test7c.c
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct _MYSTRUCT
{
char str1[10];
char str2[10];
DWORD val;
} MYSTRUCT;
extern void __stdcall Func1(MYSTRUCT *);
extern void cdecl Func2(MYSTRUCT *);
int main(int argc, char **argv)
{
MYSTRUCT my;
Func1(&my);
printf("%08X\n",my.val);
Func2(&my);
printf("%08X\n",my.val);
return(0);
}
Output
C:\MASM>test7c
00001234
00005678