The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Darmani on December 23, 2010, 06:18:37 AM

Title: Calling imported functions
Post by: Darmani on December 23, 2010, 06:18:37 AM
The following toy example illustrates my problem:


.686p
.model flat
OPTION LANGUAGE:C

include advapi32.inc
includelib advapi32.lib

_text segment para public 'CODE' use32
assume cs:_text

_start proc near
call RegCreateKey
_start endp

_text ends

_data segment para public 'DATA' use32
assume cs:_data
_data ends

end  _start


MASM is giving "error A2107: cannot have implicit far jump or call to near label" on the "call RegCreateKey" line. I have something of an understanding of what this means, but, after rereading several chapters in the MASM Programmer's Guide, no idea why it's occuring or how to fix it. I've been stuck on this for two days! Help would be appreciated.
Title: Re: Calling imported functions
Post by: MichaelW on December 23, 2010, 06:26:42 AM
Darmani,

You need to explain what you are trying to do here, because your code looks too much like a malware experiment.
Title: Re: Calling imported functions
Post by: Darmani on December 23, 2010, 06:29:25 AM
?

I am.....trying to import a function and call it. It says in the topic title.

(Yes, the start method may make absolutely no sense -- it's just the minimal thing I came up with that produces the assembly error that's been confusing me.)
Title: Re: Calling imported functions
Post by: MichaelW on December 23, 2010, 07:05:56 AM
QuoteI am.....trying to import a function and call it. It says in the topic title.

Yes, I saw that and understood it, and your repeating it does not explain what you are trying to do. Why the odd segment structure, and out of all the functions that you could have selected, why RegCreateKey?
Title: Re: Calling imported functions
Post by: Darmani on December 23, 2010, 07:20:06 AM
For the "odd" segment structure, I currently don't understand what a normal segment structure is, so the answer is the same as why an 8 year-old would fail a calculus test: there are a lot of segment structures, but only one of them is "normal." I got an error when I tried to omit the _data segment. I've been fiddling around with many of the segment and assume directives and whatnot a lot over the past few days, thinking the error had something to do with that, so, if it's left with something that looks odd, that's to be expected.

(And I got errors last time I tried to delete either segment.)

As for RegCreateKey, I believe I'm getting these errors from all imported functions, but I started my investigation with the functions in advapi32 because it's first on the include list because it comes first alphabetically. Of the functions in advapi32, I started my investigation with RegCreateKey because it gives the first assembly error, because it comes first in the file.
Title: Re: Calling imported functions
Post by: BogdanOntanu on December 23, 2010, 07:37:13 AM
Can you please explain why you did not start your tests / learning with one of the fully functional and simple examples in MASM32 examples folder?

They show you the "normal" and modern way to define .code and .data sections in your file, basic needed includes, how to invoke API's and a functional template to base your new tests / applications on it.

Choosing random code from the net and then asking why it does not work is not a very honest action when you have a lot of examples in your MASM32 folders.
Title: Re: Calling imported functions
Post by: Darmani on December 23, 2010, 07:42:44 AM
BogdanOntanu: Because I didn't think of it, and instead went straight to the manuals. Thanks for the suggestion; I'll be back here in a few days if I still can't figure it out.
Title: Re: Calling imported functions
Post by: japheth on December 23, 2010, 07:44:21 AM
Quote from: BogdanOntanu on December 23, 2010, 07:37:13 AM
Can you please explain why you did not start your tests / learning with one of the fully functional and simple examples in MASM32 examples folder?

They show you the "normal" and modern way to define .code and .data sections in your file, basic needed includes, how to invoke API's and a functional template to base your new tests / applications on it.

I don't use Masm32 and I don't agree that that's the "normal" or "modern" way. There exist better ways to program for Windows in Masm-style.
Title: Re: Calling imported functions
Post by: sinsi on December 23, 2010, 08:13:20 AM
The code looks like some from a book I have about 386 programming, not necessarily windows programming.
I think it seems fair enough adding an include and trying to call an external proc.
Title: Re: Calling imported functions
Post by: hutch-- on December 23, 2010, 09:02:45 AM
 :bg

> There exist better ways to program for Windows in Masm-style.

The Gospel according to japheth ?
Title: Re: Calling imported functions
Post by: ToutEnMasm on December 23, 2010, 10:32:50 AM

The code have a real old look.
Nobodies is obliged to use the .code .data ...
The translation of c++ code for masm can give it a better look
sample:
Quote
EXTRN   __imp__GetSystemTimeAsFileTime@4:PROC
EXTRN   __aulldiv:PROC
; Function compile flags: /Odtp
_TEXT   SEGMENT
_tim$ = -16                  ; size = 8
_nt_time$ = -8                  ; size = 8
........................................

; Line 72
   mov   esp, ebp
   pop   ebp
   ret   0
__time64 ENDP
_TEXT   ENDS
END
And it's not a virus !!
Title: Re: Calling imported functions
Post by: japheth on December 23, 2010, 10:58:06 AM
Quote from: hutch-- on December 23, 2010, 09:02:45 AM
:bg

> There exist better ways to program for Windows in Masm-style.

The Gospel according to japheth ?

I didn't say Masm32 doesn't work. It's just a bit old-fashioned with its "all's a DWORD"-philosophy. :toothy
Title: Re: Calling imported functions
Post by: dedndave on December 23, 2010, 11:08:56 AM
it has a "real old look", as Yves said, because he is mixing 16-bit and 32-bit code, which doesn't work all that well
i doubt it came from a book, or from some hacker code, for that matter
it didn't come from anyplace   :P

but - the registry is no place to fart around learning code, especially writing to it - lol
screw it up, and you may find yourself rebuilding the hard drive
if you must play in the registry...
1) start with a 32-bit program
2) start with RegOpenKeyEx/RegQueryValueEx or something
3) there are examples in the masm32\examples folder - and you can find several more by using the forum search tool
Title: Re: Calling imported functions
Post by: ToutEnMasm on December 23, 2010, 11:24:49 AM

In case it is 32 bits code,here is a sample on how to start
Quote
.NOLIST            
   include \masm32\include\masm32rt.inc
   .const
   .data
   Hkey dd 0
   mykey db ".acl",0
   .code
   start:
   invoke RegOpenKeyEx,HKEY_CLASSES_ROOT,addr mykey,NULL,KEY_READ,addr Hkey
   invoke ExitProcess,0
   ;------- proc içi ------------
   end start
Title: Re: Calling imported functions
Post by: MichaelW on December 23, 2010, 11:31:04 AM
The only things in the code that could be viewed as 16-bit are the ASSUME statements, and they could be made to work with the right seglocation keyword (although the first one would still serve no useful purpose).
Title: Re: Calling imported functions
Post by: japheth on December 23, 2010, 11:31:17 AM
To answer the OP's question:

Quote from: Darmani on December 23, 2010, 06:18:37 AM
I have something of an understanding of what this means, but, after rereading several chapters in the MASM Programmer's Guide, no idea why it's occuring or how to fix it. I've been stuck on this for two days! Help would be appreciated.

the problem is the "assume cs". With model FLAT, you're forced to a non-segmented memory model. So either remove the assume or change it to "assume cs:FLAT".


.686p
.model flat
OPTION LANGUAGE:C

include advapi32.inc
includelib advapi32.lib

_text segment para public 'CODE' use32
assume cs:FLAT

_start proc near
call RegCreateKey
_start endp

_text ends

_data segment para public 'DATA' use32
assume cs:_data
_data ends

end  _start

Title: Re: Calling imported functions
Post by: hutch-- on December 23, 2010, 11:42:14 AM
 :bg

> It's just a bit old-fashioned with its "all's a DWORD"-philosophy.

Well, I wonder what is modern, 16 bit segmented architecture ? Now i am a barbarian, I would be happy with 64 bit long mode where all are QWORD but 64 bit code is still poorly supported at the OS level at the moment. 32 bit will be with us for some time yet and it benefits from a 64 bit OS (win7 64) in terms of memory allocation, particularly with IPC extending the amount of data that can be manipulated.

As far as C/C++ equates that all collapse back to DWORD, I never did see the point when you can remove at least one level of confusion by sticking to assembler data sizes.
Title: Re: Calling imported functions
Post by: jj2007 on December 23, 2010, 12:00:05 PM
Quote from: japheth on December 23, 2010, 10:58:06 AM
It's just a bit old-fashioned with its "all's a DWORD"-philosophy. :toothy

Being more specific would only make sense if the assembler did a proper type checking. Since it doesn't, DWORDs are just fine for me :bg
Also, in a HLL you could stop a user from passing a string pointer where the proc expects a handle; in assembler, the passed variable will often be in a register, not a variable with a clearly defined type.

include \masm32\include\masm32rt.inc

MyTest PROTO: DWORD, :HANDLE

.code
AppName db "Masm32 is great!", 0
Hello db "A message:", 0

start:
invoke MyTest, offset AppName, addr Hello
exit

MyTest proc arg1, arg2:DWORD
  MsgBox 0, arg1, arg2, MB_OK
  ret
MyTest endp

end start