I am a newbie, so please make your explainations detailed.

I am writing a routine in a DLL that will execute code based on the values in a stream of DWORD's passed to the routine.

I have the routine and DLL done in MASM and it is being call ok from 'C'. In 'C' I pass the address of an array of longs to the routine. eg:

long source[] = { 10, 20, 30 };
long a = Execute( &source[0] );

I have defined the routine as:

Execute proc source:DWORD

Now my questions are as follows:

1. As a test of the routine I do a MOV eax, source so that from 'C' I get a value back that indicates the value passed. This works ok.

2. I then changed the routine to MOV eax, which I hoped would return the first DWORD pointed to by source. From the example, I was expecting a value of 10. However, I just get the value of source, just like in (1). I was under the impression that would get me the value at the address pointed to by source ie: 10. What should I do to get the value pointed to by source ?

3. When I can get the value pointed to by source, I will then use it to do a JMP to a label. What is the best way to make and use a jump table in MASM ?

I am currently defining the table as: Table dw 20 DUP (0) and in the routine I will initialize it. How do I initialize the table to contain the jump addresses indicated by labels in my routine ?
I assumed I could do this: MOV Table[0], mylabel etc etc
but this wont compile.

I would then like to use the value from SOURCE as the index into the table. ie: MOV ESI, --> JMP Table

Any help would be greatly appreciated.

Keep well.

Regs, James.
Posted on 2002-06-24 18:42:50 by James_Ladd
What should I do to get the value pointed to by source ?

just a quick example:


mov esi,[source] ;get pointer to array
mov eax,[esi] ;get first dword from array


since 'source' holds the address of your array, you need to load it into a register which you can then use as a pointer to the array. kind of. ;)

mov eax,[source]

and
mov eax,source

are the same in masm, i guess.

you don't have to initialize your jump table during runtime (except it's changing of course). you should be able to do something like this:
jumptable    dd mylabel1, mylabel2, mylabel3
Posted on 2002-06-24 18:59:04 by Tola
You should check out bitRAKE's jump table assistant. Though I myself haven't used it yet because I manually code my jump tables, it's definitely worth checking out. Try searching or go here ww.madwizard.org under the snippets library section.
Posted on 2002-06-24 20:01:21 by stryker
Thanks so much for such a quick reply.

I added instructions to MOV esi, , then MOV eax, and that gave me what I expected.

However, my 'C' program that has debug enabled is now complaining that the stack was not properly handled by the routine. I take it this is because I touched esi. Should I do a push esi and later a pop esi ?

Is there a MASM directive to let it know what registers I touch so that it automatically generates the correct epilog to the routine ?

The 'C' side of things declares the routine as __stdcall which matches the ASM code that defines:

.486
.model flat,stdcall

The other thing I did was declare the JumpTable as you suggested and it compiled a'ok, however, when I ran the example I got a "privilaged instruction" error.

Here is the code so that you can see what I am doing and let me know where I have gone really wrong: My guess is that I am not defining the labels correctly.

Execute proc value:DWORD

JumpTable dd MyLabel1, MyLabel2

MyLabel1:

mov eax, value
.if eax == 0
invoke MessageBox,NULL,addr DebugIsZero,addr AppName,MB_OK
mov eax, 0
.else
invoke MessageBox,NULL,addr DebugNotZero,addr AppName,MB_OK
mov esi,
mov eax,
.endif

MyLabel2:

ret
Execute Endp

Your help is really appreciated.

Keep well.

Regs, James.
Posted on 2002-06-24 20:27:03 by James_Ladd
I checked out the snippet but it did not work. Compile errors. Most likely me rather than the snippet.

Could you send me a routine that uses a jump table that you have done ?

Keep Well.

Regs, James.
Posted on 2002-06-24 20:42:32 by James_Ladd
I changed the code around and now it is being called from 'C' without stack errors. I still need to implement a jump table.

Can someone help me with the jump table ? I dont want to use a macro because I want to understand how to do it manually before hiding such details in a macro.

Here is the current code that works ok:

Execute proc value:DWORD
push esi
mov eax, value
.if eax == 0
invoke MessageBox,NULL,addr IsZero,addr AppName,MB_OK
jmp MyEnd
.else
invoke MessageBox,NULL,addr NotZero,addr AppName,MB_OK
mov esi,
mov eax,
.endif

MyEnd:
pop esi
ret
Execute Endp

Keep well,

Regs, James.
Posted on 2002-06-24 20:56:07 by James_Ladd
Since my routine may be called a lot of times, I would prefer to setup the jump table once and not each time through the routine. The jump table will not change once initialized.

Regs, James.
Posted on 2002-06-24 20:57:25 by James_Ladd
I just coded a small sample code, since mine involves a lot of calculations to compute the address to jump.
[size=9].686

.MODEL FLAT, STDCALL
OPTION CASEMAP:NONE

INCLUDE \masm32\include\windows.inc
INCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.lib
INCLUDE \masm32\include\user32.inc
INCLUDELIB \masm32\lib\user32.lib

.DATA

jtable DD __eax_is_0, __eax_is_1, __eax_is_2, __eax_is_3, __eax_is_4, \
__eax_is_5, __eax_is_6, __eax_is_7, __eax_is_8, __eax_is_9

data0 DB "0", 0
data1 DB "1", 0
data2 DB "2", 0
data3 DB "3", 0
data4 DB "4", 0
data5 DB "5", 0
data6 DB "6", 0
data7 DB "7", 0
data8 DB "8", 0
data9 DB "9", 0

.CODE

START:

[color=#366FF]mov edx, OFFSET jtable[/color]
[color=red]mov eax, 7[/color]
[color=#366FF]mov eax, [edx+eax*4]
jmp eax[/color]


__eax_is_0:

invoke MessageBox, 0, OFFSET data0, 0, 0
jmp __exit

__eax_is_1:

invoke MessageBox, 0, OFFSET data1, 0, 0
jmp __exit

__eax_is_2:

invoke MessageBox, 0, OFFSET data2, 0, 0
jmp __exit

__eax_is_3:

invoke MessageBox, 0, OFFSET data3, 0, 0
jmp __exit

__eax_is_4:

invoke MessageBox, 0, OFFSET data4, 0, 0
jmp __exit

__eax_is_5:

invoke MessageBox, 0, OFFSET data5, 0, 0
jmp __exit

__eax_is_6:

invoke MessageBox, 0, OFFSET data6, 0, 0
jmp __exit

__eax_is_7:

invoke MessageBox, 0, OFFSET data7, 0, 0
jmp __exit

__eax_is_8:

invoke MessageBox, 0, OFFSET data8, 0, 0
jmp __exit

__eax_is_9:

invoke MessageBox, 0, OFFSET data9, 0, 0

__exit:

invoke ExitProcess, NULL

END START[/size]
:)



BTW, you should be careful when implementing one because for example on this sample code, if the value of eax is < 0 or > 9 the app will crash.
Posted on 2002-06-24 22:44:27 by stryker
stryker,

that worked like a charm !!!
(of course I didnt realise you could do a .DATA and a .CODE withing a routine )

I like the fact that the routine doesnt initialize the jump table on each call, and it works !!

And I really liked the help the NEWBIE approach to the label names ;)

Thanks ever so much !!

If there is anything in Java or 'C' that you need let me know.

Keep well.

Regs, James.
Posted on 2002-06-24 22:56:16 by James_Ladd
And I really liked the help the NEWBIE approach to the label names


Help the NEWBIE? Heck, I write all my lable and variable names like that.


*I* need all the help I can get!
Posted on 2002-06-25 00:58:27 by Ernie
That's one thing pretty unique with ASM... labels are so common that they also serve as comments. ;)
Posted on 2002-06-26 02:54:43 by AmkG