News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

CreateThread

Started by Artoo, February 23, 2005, 11:55:10 AM

Previous topic - Next topic

Artoo

Hi everyone!

I, yet again, need your help! :(

Say I have the following code:

.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   
   includelib user32.lib
   includelib kernel32.lib

MyObj struct
  MyVar1 DD    0
  MyVar2 DD    0
  MyVar3 DD    0
MyObj ends

MyObjPTR TYPEDEF PTR MyObj

MyThread proto :DWORD

.data

g_MyObj MyObj { 0, 0, 0 }

.code

start:

  MOV g_MyObj.MyVar1 , 1
  MOV g_MyObj.MyVar2 , 2
  MOV g_MyObj.MyVar3 , 3

  invoke    CreateThread, NULL, 0, ADDR MyThread, ADDR g_MyObj, 0, NULL

  CMP  EAX, 0        ;Did we get a thread handle, if not jump to exit
  JE  Exit
  MOV  EBX, EAX        ; store thread handle in EBX
  invoke  WaitForSingleObject, EBX, INFINITE        ;Wait for thread to exit
  invoke  GetExitCodeThread, EBX, ADDR g_dwSuccess      ;What was returned by the thread?
  invoke  CloseHandle, EBX

Exit:
  invoke ExitProcess,eax


MyThread proc pData:DWORD

  MOV   EAX, [MyObj PTR pData].MyVar1
  MOV   EAX, [MyObj PTR pData].MyVar2
  MOV   EAX, [MyObj PTR pData].MyVar3
  RET
MyThread endp

end start



When I debug this code I find the thread is created ok, but when it gets inside the thread the values that are moved into EAX are not the values I originally assigned to the global structure before I created the thread.

Any ideas why its is so?

Again your help is much appreciated.

raymond

The only thing I can see at first glance is your declaration of the MyObjPTR TYPEDEF which does not contain any space in the first word. And you include a space when you use it in your thread proc.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

AeroASM

I think you may have got a little confused. Get rid of the line MyObjPTR TYPEDEF PTR MyObj because you do not use it. Put this for your thread procedure:



MyThread proc pData:DWORD

assume pData:PTR MyObj
mov eax,[pData].MyVar1
mov eax,[pData].MyVar2
mov eax,[pData].MyVar3
assume pData:NOTHING
ret

MyThread endp


Artoo

thanks for replying AeroASM,  but now i get errors when I compile.

On the first ASSUME  line I get:

  error A2008: syntax error : pData

and on the MOV lines i get:

  error A2006: undefined symbol : MyVar1


Please help!

AeroASM

Whoops, I was a little too hasty.

try this:



MyThread proc pData:DWORD

mov edx,pData
assume edx:PTR MyObj
mov eax,[edx].MyVar1
mov eax,[edx].MyVar2
mov eax,[edx].MyVar3
assume edx:NOTHING
ret

MyThread endp


Artoo

Thanks AeroASM, that worked!   :dance:

Now that I have a solution, I am wondering why it was a problem in the first place.

My Original code
MOV   EAX, [MyObj PTR pData].MyVar1
Your code:
mov edx,pData
assume edx:PTR MyObj
mov eax,[edx].MyVar1


Firstly I am confused as to the position of the PTR in the ASSUME, which is before the 'type' MyObj, compared to the 'casting'  in my code where PTR is after the 'type'. 

My code compiles, but what exactly is it doing?  I thought 'casting' pData to the type I want and then accessing the member of the structure would be acceptable?   :dazzled:  <--- we really need a scratching head icon.

hmmmmm.... any thoughts?







Artoo

Looking at the dissassembled code:

Mine:
  MOV   EAX, [MyObj PTR pData].MyVar1
0040107F  mov         eax,dword ptr [pData]


AeraASM:
mov edx,pData
00401082  mov         edx,dword ptr [pData]
assume edx:PTR MyObj
mov eax,[edx].MyVar1
00401085  mov         eax,dword ptr [edx] 


So whats the difference here?  if in AeroASM code, EDX is pData, then  my code"mov eax,dword ptr [pData]" is the same as "eax,dword ptr [edx]"

Hmmm, am I assumnig something I shouldnt be.....?


tenkey

#7
You've run into a limitation of the processor. It cannot use a pointer while it is still in memory. So it is necessary to move the pointer to a register.

The assembler simply reduces all the address components to form one valid addressing mode. The valid modes are immediate, register, and memory. The valid memory modes can be viewed as variations of the most complex addressing mode, [basereg + indexreg*scale + displacement]. There are limits to the addressing modes (e.g., scale can only be the constants 1, 2, 4, or 8). Valid memory modes cannot use a data pointer that's stored in memory. If the address references a pointer, it will simply use the pointer as data.

Or to put it another way...

mov eax,[MyObj PTR pData].MyVar1

has been reduced to

mov eax, [ADDROF(pData) + OFFSETOF(MyVar1)]

So, in quasi-C, you're getting pData.MyVar1 instead of (*pData).MyVar1.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Artoo

aaaaah...I seee!  :8)

so am I right in saying that
mov eax,[MyObj PTR pData].MyVar1

is getting the address off the stack and anding  the offset of MyVar1? and thus moving a value in EAX that is relative to the current stack position and not relative to the value that pData holds?







AeroASM

#9
I don't think that code will even compile. PTR does not mean pointer or anything else. It is just a random phrase, used in two places:

Where the size of a memory operand is otherwise unknown: dword ptr [ebx]

With the assume directive: assume edx:ptr MyObj

All the assume directive does is tell MASM that a particular register points to a kind of structure, so it knows what you are talking about when you ask it for MyVar1.

tenkey

#10
Quote from: Artoo on February 24, 2005, 12:07:06 AM
so am I right in saying that
mov eax,[MyObj PTR pData].MyVar1

is getting the address off the stack and anding  the offset of MyVar1? and thus moving a value in EAX that is relative to the current stack position and not relative to the value that pData holds?

Correct, EAX is getting the pointer pData itself. When you try to get MyVar2 in the same way, you get the DWORD that follows the pData pointer.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8