News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Some question...

Started by felipe, May 17, 2017, 01:44:27 PM

Previous topic - Next topic

felipe

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:

aw27

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  :(

felipe

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

aw27

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:

jj2007

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.

felipe

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:

felipe

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:

felipe


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?

felipe

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

felipe

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:

felipe

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:

aw27

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.

felipe

 :t Thanks for your reply.

hutch--

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.

felipe

Thanks a lot Hutch, i was looking a good explanation for using the LOCAL directive.  :t