flat assembler
Message board for the users of flat assembler.

Index > Windows > pointer to structure

Author
Thread Post new topic Reply to topic
thecf



Joined: 23 Dec 2006
Posts: 23
thecf 21 Oct 2007, 21:21
I am writing a dll file and want to pass a struture to my dll funtion by reference. How can i do this? I've tried the following:

Code:
C code--------------------------

typedef struct test {
DWORD x;
DWORD y;
} mytest;

TestFunction(&mytest);

x should = 1
y should = 2

ASM code--------------------------

TestFunction:

  push  ebp
  mov   ebp,esp
  
  mov   dword [ebp+4],1
  mov   dword [ebp+8],2
  pop    ebp
  retn
    


Any help will be appreciated guys...
Post 21 Oct 2007, 21:21
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 21 Oct 2007, 22:41
By passing something by reference means that in the stack resides the pointer, not a copy of the structure so you accessed it wrong.

Here a example code:
Code:
format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'

struct test
  x dd ?
  y dd ?
ends

section '.code' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
        mov     eax,TRUE
        ret
endp



; VOID TestFunction(test *pTest);
proc TestFunction pTest
  ;push ebp/mov  ebp, esp

  mov eax, [pTest] ; mov eax, [ebp+8] (Loads structure pointer into EAX)

; Now we write to the structure pointed by EAX
  mov [eax+test.x], 1
  mov [eax+test.y], 2

  ret ;leave/retn
endp

section '.edata' export data readable

  export 'TEST.DLL',\
         TestFunction,'TestFunction'

section '.reloc' fixups data discardable    
Post 21 Oct 2007, 22:41
View user's profile Send private message Reply with quote
thecf



Joined: 23 Dec 2006
Posts: 23
thecf 22 Oct 2007, 00:00
The code you posted did not populate the structure that was passed to the test function. I got the following working? Could it be improved?

Code:
format PE DLL
entry DllEntryPoint

section '.code' code readable executable

  DllEntryPoint:

    mov   eax,1
    ret

  ; void TestFunction (test *pTest)
  TestFunction:

    mov   ebp, dword [esp+4]

    arg1 equ dword [0+ebp]
    arg2 equ dword [4+ebp]

    mov   arg1, 1
    mov   arg2, 2

    ret

section '.edata' export data    readable

  ; image export directory
  dd 0,0,0,RVA dll_name,0,1,1
  dd RVA addr_tab
  dd RVA name_tab
  dd RVA ordinal_tab

  ; dll name
  dll_name db 'test.dll',0

  ; function address table
  addr_tab dd RVA TestFunction

  ; function name table
  name_tab dd RVA ex_TestFunction

  ; export name table
  ex_TestFunction db 'TestFunction',0

  ; ordinal table
  ordinal_tab dw 0
    
Post 22 Oct 2007, 00:00
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 22 Oct 2007, 02:13
Quote:

The code you posted did not populate the structure that was passed to the test function

What do you mean??

Well, about optimizations use eax, edx, or ecx at "mov reg, dword [esp+4]" since the calling conventions requires ebp register preservation (among others) and you are returning with a destroyed version.

Since seems that you don't want to include 'win32a.inc' you could still "beautify" the code this way:
Code:
  ; void TestFunction (test *pTest) 
  TestFunction: 
    virtual at eax
      .x dd ?
      .y dd ?
    end virtual

    mov   eax, dword [esp+4]

    mov   [.x], 1 ; mov [eax], 1
    mov   [.y], 2 ; mov [eax+4], 2
; No need for "dword" since fasm obtains the data size from the labels

    ret
; Regs that must be keep its original value at return: EBX, ESP, ESI, EDI, EBP (At least for cdecl, stdcall, pascal and fastcall calling conventions)    
Post 22 Oct 2007, 02:13
View user's profile Send private message Reply with quote
asmfan



Joined: 11 Aug 2006
Posts: 392
Location: Russian
asmfan 22 Oct 2007, 08:47
thecf wrote:

Code:
  ; void TestFunction (test *pTest)
  TestFunction:

    mov   ebp, dword [esp+4]

    arg1 equ dword [0+ebp]
    arg2 equ dword [4+ebp]

    mov   arg1, 1
    mov   arg2, 2

    ret
    

BTW the code is wrong, calling conventions assume ebp is preserved through calls stdcall in particular, another moment - who corrects the stack - if procedure itself, then ret 4 i bet in dll stdcall procs should reside.

_________________
Any offers?
Post 22 Oct 2007, 08:47
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 22 Oct 2007, 14:47
Quote:

if procedure itself, then ret 4 i bet in dll stdcall procs should reside.

Yep, stdcall and pascal needs this and DLL's procs normally are stdcall. I forgot to point that out.
Post 22 Oct 2007, 14:47
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.