The MASM Forum

General => The Campus => Topic started by: ColdBackup on October 04, 2013, 12:42:49 PM

Title: Set of questions on how to write beginner-level code for ml64.
Post by: ColdBackup on October 04, 2013, 12:42:49 PM
Hello everyone.  I'm glad to be joining the forum.  This seems like the only live place for MASM discussions on the whole internet.

So... I finally started reading a book on MASM.  Had been planning to learn the basics for a while.  Of course I ran into some difficulties, many more of which I'm sure would accompany me throughout this journey.  The book uses x86 code so I'm trying to alter it a bit to make it working on my x64 system.  Hope you don't mind if I use this thread for related questions.  Guess I'll start.

While browsing MSDN to find more information about directives used in the code, I noticed a remark that .MODEL directive is not used in ml64.  I would like to know what should replace it if anything.  Also, this and other directives in the book appear to be in lower case letters, but it's in upper case on MSDN website.  Does it mean the directives are case insensitive in MASM?

That's it for now.  Time to take a break for me and wait for some guidance before moving forward.

Thanks.
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: dedndave on October 04, 2013, 08:35:28 PM
welcome to the forum   :t

.MODEL applied to the segmented-memory aspects of the older intel processors
if you want to create a 16-bit EXE, you still use it
well - 16-bit apps don't run under 64-bit OS's, but they do run under 32-bit OS's

jumping into 64-bit code without the stepping stone of 32-bit won't be easy
there are additional stack-alignment issues that have to be dealt with
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: Gunther on October 04, 2013, 08:44:03 PM
Hi ColdBackup,

welcome to the forum.

Gunther
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: ColdBackup on October 13, 2013, 03:56:59 PM
Hi there,

Finally, I had some time today to pick up where I left off, after bothersome week.

Quote from: dedndave on October 04, 2013, 08:35:28 PM
welcome to the forum   :t
Quote from: Gunther on October 04, 2013, 08:44:03 PM
welcome to the forum.
Thank you.

Quote from: dedndave on October 04, 2013, 08:35:28 PM
jumping into 64-bit code without the stepping stone of 32-bit won't be easy
With that in mind, I tried to feed aforementioned sample code from the book to ml (x86) instead, but it generated a couple of errors.


.386
.model flat, c
.stack 100 h
.data
num1 sdword ?
num2 sdword ?
.code
main proc
mov num1,5
mov eax,num1
mov num2,eax
ret
main endp
end



(3) : error A2206:missing operator in expression
(2) : error A2206:missing operator in expression


Would someone please tell me what I'm doing wrong here?

Thanks


P.S.  I was surprised to discover after compiling simplistic C++ program with /FA option, that resultant assembly code also generated errors during compilation.  Go figure...
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: jj2007 on October 13, 2013, 05:22:29 PM
It's a simple syntax error in line 2: 100 h ==> 100h
You'll get a linker error then. Change the last line to end main

Even better, use our standard Hello World template:
include \masm32\include\masm32rt.inc

.code
AppName   db "Masm32:", 0

start:   MsgBox 0, "Hello World", addr AppName, MB_OK
   exit

end start


Have a look at \masm32\include\masm32rt.inc, it's a fascinating lecture ;-)
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: hutch-- on October 13, 2013, 07:02:12 PM
You can successfully ditch the .STACK directive as the stack size in a 32 bit PE file is set by the linker, not the assembler.
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: jj2007 on October 13, 2013, 07:25:50 PM
Quote from: hutch-- on October 13, 2013, 07:02:12 PM
You can successfully ditch the .STACK directive...

Indeed, .stack gets ignored completely. If for good reasons you need to set the stack size, add /Stack:200,100 to the linker's commandline, where 200=bytes of reserves stack, 100=bytes of committed stack. Note it's decimal values, use 0x100 if you prefer hex notation.

Normally you don't need any option because the linker reserves by default 1048576 bytes, of which 4096 are committed. If your proggie needs more, the OS commits more automatically (for advanced users: Probing the Stack (http://masm32.com/board/index.php?topic=1363.0) by DednDave and StackBuffer (http://masm32.com/board/index.php?topic=94.msg22404#msg22404)).
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: ColdBackup on October 18, 2013, 09:26:26 AM
Quote from: jj2007 on October 13, 2013, 05:22:29 PM
It's a simple syntax error in line 2: 100 h ==> 100h
Thank you.  The error disappeared now.

Quote from: jj2007 on October 13, 2013, 05:22:29 PM
You'll get a linker error then. Change the last line to end main
It worked.  Thanks again.
I also figured providing /entry:main /subsystem:console would probably make it link correctly and it turned out to be so.

Quote from: jj2007 on October 13, 2013, 05:22:29 PM
Even better, use our standard Hello World template:
include \masm32\include\masm32rt.inc

.code
AppName   db "Masm32:", 0

start:   MsgBox 0, "Hello World", addr AppName, MB_OK
   exit

end start


Have a look at \masm32\include\masm32rt.inc, it's a fascinating lecture ;-)
I've just installed MASM32 SDK so it'll take some time for me to get used to it.  By the way, I had some error messages popping up during installation:

inc2l.exe - Ordinal Not Found
... could not be located in the dynamic link library
C:\\Windows\AppPatch\AcLayers.dll

I hope it's not a big deal.

Quote from: hutch-- on October 13, 2013, 07:02:12 PM
You can successfully ditch the .STACK directive as the stack size in a 32 bit PE file is set by the linker, not the assembler.
Quote from: jj2007 on October 13, 2013, 07:25:50 PM
Indeed, .stack gets ignored completely. If for good reasons you need to set the stack size, add /Stack:200,100 to the linker's commandline, where 200=bytes of reserves stack, 100=bytes of committed stack. Note it's decimal values, use 0x100 if you prefer hex notation.

Normally you don't need any option because the linker reserves by default 1048576 bytes, of which 4096 are committed. If your proggie needs more, the OS commits more automatically (for advanced users: Probing the Stack (http://masm32.com/board/index.php?topic=1363.0) by DednDave and StackBuffer (http://masm32.com/board/index.php?topic=94.msg22404#msg22404)).
Thank you for this information.  Will come in handy.

I finally compiled and linked my code successfully so I would like to thank everyone who responded to help.
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: ColdBackup on October 18, 2013, 09:48:29 AM
I have a couple of questions regarding '.model'.

1.  If 'c' is specified, does it mean that code can interact with functions written in C, or does it mean that functions written in ASM have same parameter mechanics of C functions?
2.  If 'stdcall' is specified, does it mean that code can interact with function written in C++, or does it mean that functions written in ASM have same parameter mechanics of C++ functions?
3.  Can both be specified?

Thanks
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: dedndave on October 18, 2013, 10:46:38 AM
the ordinal not found error - don't worry about that one
i forget the exact cause, but it is benign

as to .MODEL...
we generally use StdCall, because the windows API functions use this model
more specifically, we use the Flat model and StdCall convention
        .MODEL  Flat,StdCall

i seem to recall a few MSVCRT functions that use the C calling convention
we balance the stack after the call to make it work

as for your own functions, you can specify a calling convention on the PROC line
otherwise, the convention specified in .MODEL is used

MyFunc PROC C
;
        ret

MyFunc ENDP


the parameters are pushed in the same order, but the caller is responsible for cleaning them off the stack
i'm not sure if the assembler does this with INVOKE, as i haven't used it in modern times - lol
maybe if it's PROTO'typed that way
MyFunc PROTO C
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: jj2007 on October 18, 2013, 04:28:31 PM
You can mix C/C++ and assembly freely as long as the same model is specified in both, e.g.
C:
extern void   __cdecl xTimerStart(void);      // uses QPC and
extern int   __stdcall xTimerEnd(void);      // returns microseconds


Assembly:
xTimerStart proc C        ; C calling convention
        NanoTimer()
        ret
xTimerStart endp
xTimerEnd proc        ; stdcal
        mov eax, NanoTimer(µs)        ; return µs in eax
        ret
xTimerEnd endp


NanoTimer (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1171) is a macro, but of course you can use anything programmed in assembly there.
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: sinsi on October 18, 2013, 04:56:36 PM
When using ml64, you will get a syntax error for these lines
.686
.model <whatever>
end <entrypoint>

a 64-bit cpu is assumed to be at least .686
there is one model and one calling convention (fastcall)
entrypoint should be part of the linker's command line, it should also be public i.e.
public start
start:
...
end
Title: Re: Set of questions on how to write beginner-level code for ml64.
Post by: TWell on October 18, 2013, 05:52:13 PM
; Sample x64 Assembly Program
; Fixed to POAsm
includelib kernel32.lib
includelib user32.lib
extern ExitProcess: PROC
extern MessageBoxA: PROC
.data
caption db 'Hello64', 0
message db 'Hello 64-bit World!', 0
.code
WinMainCRTStartup PROC ; Windows GUI entry point
  sub    rsp,28h      ; shadow space, aligns stack
  mov    rcx, 0       ; hWnd = HWND_DESKTOP
  mov    rdx, OFFSET message ; LPCSTR lpText
  mov    r8,  OFFSET caption ; LPCSTR lpCaption
  mov    r9d, 0       ; uType = MB_OK
  call   MessageBoxA  ; call MessageBox API function
  mov    ecx, eax     ; uExitCode = MessageBox(...)
  call ExitProcess
WinMainCRTStartup ENDP
END ;WinMainCRTStartup   ; entry point