News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Set of questions on how to write beginner-level code for ml64.

Started by ColdBackup, October 04, 2013, 12:42:49 PM

Previous topic - Next topic

ColdBackup

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.

dedndave

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

Gunther

You have to know the facts before you can distort them.

ColdBackup

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...

jj2007

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 ;-)

hutch--

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.

jj2007

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 by DednDave and StackBuffer).

ColdBackup

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 by DednDave and StackBuffer).
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.

ColdBackup

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

dedndave

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

jj2007

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 is a macro, but of course you can use anything programmed in assembly there.

sinsi

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

TWell

; 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