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.
Darmani,
You need to explain what you are trying to do here, because your code looks too much like a malware experiment.
?
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.)
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?
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.
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.
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.
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.
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.
:bg
> There exist better ways to program for Windows in Masm-style.
The Gospel according to japheth ?
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 !!
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
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
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
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).
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
: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.
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