Page 1 of 1

MASM - Getting started with MASM part 2

#1 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 858
  • View blog
  • Posts: 2,282
  • Joined: 28-March 11

Posted 17 October 2011 - 06:17 PM

MASM - Getting started Part 2

General program layout.
There are a few sections in an Assembly program:
.data
This is where all of your initialized data goes. App strings, numbers etc... It takes up room in your exe i.e. if you initialize a 5000 byte array here, your exe will be 5000 bytes bigger.

.data?
This is where all of your UN-initialized data goes. String buffers, arrays, structures, variables etc... It DOES NOT take up room in your exe.

.const
This is where you can put all values that don't change in your code, i.e. IAmTrue equ TRUE

.code
This is where all your program code goes

Technically you can have 1 asm file with everything in it. I don't do that, I have a few files:
Main.asm - basic code is here
strings.inc - all predefined strings here
data.inc - all uninitialized data here
WndProcs.asm - all window procedures are here
protos.inc - protos for procs are here
equates.inc - equates are here

I will be referring to the MASM32 package in this tut. You can find a link to MASM32 in this tut. It contains C headers/libs from the SDK translated to MASM inc/lib files

A bare minimum exe:
.586
.model flat, stdcall
option casemap:none

include kernel32.inc

includelib kernel32.lib

.code
BareApp:

	invoke	ExitProcess, 0
end BareApp


.586 tells ML what mnemonics you want to use. Unless you are doing something exotic, .386 - .686 is fine
.model flat, stdcall tells ML we want the flat memory model. This is what all Win32 apps use. stdcall is the procedure calling convention we are going to use - The called proc cleans up the stack
option casemap:none tells ML variables, labels, proc names etc... are case sensitive meaning exitprocess and ExitProcess are two different things (helps cut down on bugs)

On a side note. If you wanted to get creative you could do: GoAway equ ExitProcess and instead of invoke ExitProcess, 0 you could do invoke GoAway, 0, you could even redefine registers. EQU is a cool tool.

Next is include, and includelib. the include directive tells ML to process kernel32.inc. This file contains the prototypes for the functions in kernel32.dll. IncludeLib tells the linker how to resolve proc names.

In MASM, you don't need a "WinMain" as your entry point. In the above sample, the label BareApp is the entry point, whatever you name it, you need a corresponding end labelname at the end.

Hey, that is all great and all but how do I make an exe after I type all my code?
Good question. There are many ways: batch files, nmake, make, IDE's, even text editors allow you to shell out to ML.

Here is a sample batch file from MASM32:
@echo off

if not exist rsrc.rc goto over1
\masm32\bin\rc /v rsrc.rc
\masm32\bin\cvtres /machine:ix86 rsrc.res
:over1

if exist %1.obj del %1.obj
if exist %1.exe del %1.exe

\masm32\bin\ml /c /coff %1.asm
if errorlevel 1 goto errasm

if not exist rsrc.obj goto nores

\masm32\bin\Link /SUBSYSTEM:WINDOWS /OPT:NOREF %1.obj rsrc.obj
if errorlevel 1 goto errlink

dir %1.*
goto TheEnd

:nores
\masm32\bin\Link /SUBSYSTEM:WINDOWS /OPT:NOREF %1.obj
if errorlevel 1 goto errlink
dir %1.*
goto TheEnd

:errlink
echo _
echo Link error
goto TheEnd

:errasm
echo _
echo Assembly Error
goto TheEnd

:TheEnd

pause


I use RadASM as my IDE, I just set a few paths and Assembling and linking is easy. BTW, we don't "compile" in Assembly, we Assemble and link. :-)

Before we get on to a sample app, let's go over a few things.

DOS and 16bit ASM use Interrupts to interact with the OS, screen, drives, files etc... Win32 Asm (Which we will be doing) uses the Windows API, so if you have experience with it that is a plus. MSDN will be your best friend or you can
download the SDK from microsoft (you can even get it on cd for free from MS, just pay shipping)

Variables: One thing I could never grasp in the HLLs are the MANY different variable types when there are only a handful the CPU uses - BYTE (1 byte), WORD (2 bytes), DWORD (4 bytes), FWORD (6 bytes), QWORD(8 bytes), TBYTE(10 bytes), REAL4(4 bytes), REAL8(8 bytes), REAL10(10 bytes)
For general Windows programming, you will mostly use BYTE, WORD, and DWORD. Naturally, 64bit adds a few others.
You may be tempted to use the smallest data type (BYTE) for something like a Boolean variable, but that will actually give you a performance penalty since memory is DWORD aligned, so use a DWORD for a Boolean variable.

Everything is basically a pointer to some memory.

Yes you can use COM in Assembly, it is far beyond this tut and is hair pulling at first.

I seen a lot of newbies over the years or people that use different Assemblers saying, I don't want to use the MASM high level stuff... bah, the .ifs, .whiles produce decent code. I say, use em at first until you get comfy with ASM.

A little info on Anti-Virus programs - THEY SUCK when writing in Assembly. They don't like the small code, the way sections are aligned, the order of certain instructions, whatever. Ways to shut them up -
include a manifest and a version block in your exe, re-order some instructions/API calls.

Next up - Creating our first app in Assembly!

Is This A Good Question/Topic? 1
  • +

Replies To: MASM - Getting started with MASM part 2

#2 carlosm7  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 16
  • Joined: 22-April 10

Posted 17 October 2011 - 10:48 PM

View PostGunnerInc, on 17 October 2011 - 06:17 PM, said:

.data?
This is where all of your UN-initialized data goes. String buffers, arrays, structures, variables etc... It DOES NOT take up room in your exe.

First, thank you for this tutorials.

I wanted to add something just in case somebody wants to also write assembly code in Linux.

I was trying to do a mix of C++ and assembly in Linux, and then my program started ending unexpectedly and experiencing data corruption. I managed to isolate the problem to a few assembly function calls. Then I realized that all of the functions had something in common: the uninitialized data segment, ".data?"

All of the problems started when I decided to put all uninitialized data on the uninitialized data segment, and ended when I decided to put all of the data back on the initialized data segment and lose all uninitialized data segments, as it seems memory for the uninitialized data segments was not being allocated, or the appropriate pointers where not being updated by the Linux program loader, or some other problem. I was using NetBeans IDE, the GNU tool collection, and JWasm.

View PostGunnerInc, on 17 October 2011 - 06:17 PM, said:

.model flat, stdcall
option casemap:none


When I used to write Win32 assembly code, I preferred to instruct my IDE (Visual Studio 6 at that time) to use the following switches:

/c /coff /Cp /Cx /GZ /Zi

This way you only need to worry about including ".model flat" and let the IDE automatically set up everything else via command line switches.

The "/Zi" switch tells MASM to include debug information, even in release mode, but it's OK, as the linker will remove all debug information when linking in release mode, so you can use the same configuration for all ".asm" files in all modes and forget about it.

(By the way, IIRC, "includelib" did not seem to work in JWasm/Linux.)
Was This Post Helpful? 0
  • +
  • -

#3 GunnerInc  Icon User is offline

  • "Hurry up and wait"
  • member icon




Reputation: 858
  • View blog
  • Posts: 2,282
  • Joined: 28-March 11

Posted 18 October 2011 - 03:54 PM

With MASM, you can only write for the Windows OS, so I am not concerned with Linux. I don't thing JWASM uses includelib for Linux.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1