I was doing some researching and i did get understanding about some items usually used in the masm32 sdk code.
But i still have a doubt about the proto directive. Please see this code (it's like that because i was investigating, but works correctly). Why i have to use proto if i don't use proc nor invoke? The explanation commented in the code is supposed to correspond to the proc directive, but not for the call instruction. I tried using extern, extrn, externdef. They assembled but there was a problem with the linker.
As i said, i was doing some research, i'm not trying to debate wich style of coding is better. I just want to know more. Of course, if you want to say something about that, no problem. :icon_mrgreen: :icon14:
.386 ; Required because the default for the assembler is 8086.
.model flat,stdcall ; Required because the default for the assembler is small, pascal.
includelib c:\masm32\lib\user32.lib ; Required if you don't type in the console the link commands.
includelib c:\masm32\lib\kernel32.lib
.data
client_area byte 'Hello, low world!',0
title_ byte ' ',0
pointer1 dword client_area ; To avoid the offset directive.
pointer2 dword title_
.code
start:
ExitProcess proto :dword ; The assembler needs this to know the number of parameters
MessageBoxA proto :dword, :dword, :dword, :dword ; passed to the function.
push 0
push pointer2
push pointer1
push 0
call MessageBoxA
push 0
call ExitProcess
end start
Note: basically i was learning what the include files are (including windows.inc) and some directives. :bgrin:
Quote from: felipe on May 17, 2017, 01:44:27 PM
I tried using extern, extrn, externdef. They assembled but there was a problem with the linker.
You can use extern, externdef, but will have to use the decoration in the call. Ex: call Exitprocess@4 :(
aw27 thanks a lot! Now i see, this are the real names of the functions that use the stdcall calling convention. I also understood the numbers and the letter A. But what happend with the underscores? If i use them i get an linker error showing the names with always 1 added underscore (ex. if i use 1 then are show 2, if i use 2 then are show 3).
Also the msdn site shows: __stdcall but using this in: .model flat,__stdcall gives me errors in assembly time.
Thanks for your replies. :t
Quote from: felipe on May 17, 2017, 03:40:11 PM
But what happend with the underscores?
Don't use underscores.
ex: extern stdcall ExitProcess@4 :proc
Quote
.model flat,__stdcall
No undescores. :badgrin:
The PROTO tells the assembler "I am including something that you won't find in this source. But the linker will know".
For good reasons, almost everybody in this forum uses
include \masm32\include\masm32rt.inc
Open this file in notepad, and try to understand what it does. And stop using C:\Masm32\... - by design, all paths in the Masm32 SDK are relative to the root of the drive where Masm32 was installed. This can be C:, of course, but others may use D: or Z:, and therefore include \masm32\include\masm32rt.inc without a drive letter is much, much better.
Quote from: aw27 on May 17, 2017, 04:13:51 PM
Quote from: felipe on May 17, 2017, 03:40:11 PM
But what happend with the underscores?
Don't use underscores.
ex: extern stdcall ExitProcess@4 :proc
Quote
.model flat,__stdcall
No undescores. :badgrin:
Yeah, but why is this? It's just for c++, for a newer release of ml, is implicit already, why? :eusa_snooty:
Quote from: jj2007 on May 17, 2017, 07:19:19 PM
The PROTO tells the assembler "I am including something that you won't find in this source. But the linker will know".
For good reasons, almost everybody in this forum uses
include \masm32\include\masm32rt.inc
Open this file in notepad, and try to understand what it does. And stop using C:\Masm32\... - by design, all paths in the Masm32 SDK are relative to the root of the drive where Masm32 was installed. This can be C:, of course, but others may use D: or Z:, and therefore include \masm32\include\masm32rt.inc without a drive letter is much, much better.
Good explanation, thanks JJ. And yes i already know that, it was just a mistake because it was too late... :icon_cool:
Quote from: jj2007 on May 17, 2017, 07:19:19 PM
The PROTO tells the assembler "I am including something that you won't find in this source. But the linker will know".
So proto acts the same as extern but without the use of the decorations and, also doing type checking, right?
Quote from: felipe on May 17, 2017, 11:57:42 PM
Quote from: aw27 on May 17, 2017, 04:13:51 PM
Quote from: felipe on May 17, 2017, 03:40:11 PM
But what happend with the underscores?
Don't use underscores.
ex: extern stdcall ExitProcess@4 :proc
Quote
.model flat,__stdcall
No undescores. :badgrin:
Yeah, but why is this? It's just for c++, for a newer release of ml, is implicit already, why? :eusa_snooty:
Here is the code using the decorations and the extern directive, the program work fine (assembly, linking and running). But using in the names (ex. _ExitProcesses@4 and of course in __stdcall too) gives those errors that i commented. In the msdn site said __stdcall and "Name-decoration convention An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated as follows: _func@12".
.386 ; Required because the default for the assembler is 8086.
.model flat,stdcall ; Required because the default for the assembler is small, pascal.
includelib \masm32\lib\user32.lib ; Required if you don't type in the console the link commands.
includelib \masm32\lib\kernel32.lib
.data
client_area byte 'Hello, low world!',0
title_ byte ' ',0
pointer1 dword client_area ; To avoid the offset directive.
pointer2 dword title_
.code
start:
extern ExitProcess@4 :near
extern MessageBoxA@16 :near
push 0
push pointer2
push pointer1
push 0
call MessageBoxA@16
push 0
call ExitProcess@4
end start
Ok i guess i got it. Seems like the assembler stores the names identifiers (probably when using the simplified segments directives) with an added underscore (internally), so it's not necessary to the user write one (and that explains the duplicated underscores mentioned above). :icon14:
Quote from: felipe on May 18, 2017, 12:32:00 AM
Ok i guess i got it. Seems like the assembler stores the names identifiers (probably when using the simplified segments directives) with an added underscore prefix, so it's not necessary to the user write one (and that explains the duplicated underscores mentioned above). :icon14:
Quote from: felipe on May 18, 2017, 12:32:00 AM
Seems like the assembler stores the names identifiers (probably when using the simplified segments directives) with an added underscore (internally)
Yes, nice assemblers do that and we don't have to bother with that.
:t Thanks for your reply.
felipe,
You can do simple things without using the PROC directive but when you start making more complex apps they become a necessity. By using a PROC, you can allocate LOCAL variables which are really useful and simple to use. They automatically use stack space and only have scope for the duration of the proc. This saves you from having a massive number of global variables that all must have unique names.
Here is a simple example. 1536 bytes. If you use a .DATA section, it will be 2.5k.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
.686p ; create 32 bit code
.mmx ; enable MMX and XMM
.xmm
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
.code
; --------------------------------------------
; in the code section the data is not writable
; --------------------------------------------
caption db "Title",0
text db "Message Text",0
ptitle dd caption
ptext dd text
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
push 0
call ExitProcess
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
push 0
push ptitle
push ptext
push 0
call MessageBox
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start
Just to note, I have used ML.EXE version 14 which has unintelligible error messages, looks like Microsoft have let the dorks at it.
Thanks a lot Hutch, i was looking a good explanation for using the LOCAL directive. :t