This chapter describes some basics of machine language programming, but beginners should may read a good book about that. To get your first program started you should enter the directory SRC and start 'Make.bat'. The next step is to include the directory BIN to your search path. If you start 'Install.bat' latter won't be done. It is a good idea to update the PATH definition in your AUTOEXEC.BAT.
If TMA is executable from everywhere get into one of the example directories and assemble the sources. For instance:
CD EXAMPLES\DATALAND
TMA DATALAND.ASM
Some example sources need to be assembled to EXE files. If this is the case, an error message is omitted. Use the -e switch to force EXE generation:
TMA -e RELIEF.ASM
Have fun!
We have three sorts of instructions when programming in assembly.
mnemonics This are the instructions your CPU will work on. data definitions They define data areas, lists and structures, the places where you can store your data. directives Assembler commands. They tell TMA how to handle the source and how to generate code.
Mnemonics, the names of real CPU instructions, usually need operands which indicate what type of data to use for the specified operation.
MOV DX,10 ; Load register DX with decimal 10
Values may be stored in registers or memory. To reserve memory space, use the DB/DW/DD etc instructions:
DB ? ;Reserve a byte
DW ? ;Reserve a word
You can continue a line in the next one by using the backslash '\'. As far as I know this is also possible in Borland's TASM when in IDEAL mode.
db"Hello !"\
,10,13,0
NOTE: DON'T USE THE BACKSLASH *WITHIN* OPERANDS!
Nearly every x86 instruction that needs operands, uses effective adresses (I'll call the EAs).
With EAs you can:
- Load memory with register contents or vice versa.
- Load memory or a register with a constant value.
Their syntax is not too complex at all and they don't differ much from instruction to instruction.
Usually you'd write
to load AX with the contents of memory address 0, but you may also do that a smarter way. TMA recognizes that AX is a WORD register and you may leave off explicit notations for transfer sizes:
MOV AX,word ptr[0]
If you have to indicate the transfer size, because you don't use registers or the syntax is ambiguous, a single letter is enough to tell TMA what to do. This is very compatible to A386:
MOV AX,[0]
MOV B[1000H],200 ;BYTE transfer PUSH D[0] ;Pushes a DWORD on stack.
At this time there're three possible abbrevviations:
byte ptr [...] -> B[...]
word ptr [...] -> W[...]
dword ptr [...] -> D[...]
NOTE: When using PUSH or POP instructions, a WORD transfer is assumed.
x86 processors know EAs for 16bit and for 32bit addresses and their syntaxes vary:
Effective Adresses (16 bit)
A 16bit-EAs may contain:
- 1 base register, BX or BP together with
- 1 index register, SI or DI
- 1 constant displacement, signed BYTE or signed WORD
- a base or index register on its own.
For instance:
MOV AX,[BX]
MOV AX,[BP]
MOV AX,[SI]
MOV AX,[DI]
MOV AX,[BX+SI]
MOV AX,[BX+DI]
MOV AX,[BP+SI]
MOV AX,[BP+DI]
MOV AX,[BX+SI+100]
MOV AX,[DI-100]
MOV AX,[100]
A 32bit-EA may contain:
- any 32bit register except SP as base or index
- a scaling factor for the index register (2,4 or 8)
- a constant displacement of signed WORD or signed DWORD
MOV [ECX+EBX],EAX
MOV AX,[EAX+EBX*4+100]
MOV AX,[EAX+100]
LEA EAX,[EAX+EAX*8] ;Multiplies EAX by 9
TMA knows 2 classes of labels for code and data. The label type is recognized by its syntax. When defining a code label, let a ':' follow. When referring to a code label, it's address is returned. When referring to a data label, the contents of it's address are returned; you don't have to put them in braces. If you need the contents of a code label address, put it braces.
MOV AX,[codelabel]
If you need the address of a data label, use the OFFSET directive or its abbrevviation OFS.
MOV AX,OFFSET datalabel
MOV AX,OFS datalabel
When working on large sources it's quite difficult to name labels a reasonable way, especially if you just need to know that they are there. For this reason, local labels, are implemented. They may be defined more than once with the same name.
A86/A386 compatible local code labels
To be compatible to A86/A386 a local label must start with a single letter followed by a number. You must explicitly indicate forward jumps when reffering to them.
l1: JMP >a2
a1: JMP l1
a2: JMP a1
NOTE: Even crossed jumps are allowed. A86/A386 will omit error messages on them:
l1: JMP >l1
JMP l1
l1:
REMARK: This is about future extensions for compatibility to TASM and MASM but I'm not quite sure how they're really used. Tell me.
TMA is very useful for beginners. Red tape is not needed at all while still having full control of the generated code. At last there's no problem generating COM files. Here's an example (EXAMPLES\SNIPPETS\HELLO.ASM):
MOV DX,msg
MOV AH,9
INT 21H
MOV AX,4C00h
INT 21H
msg: DB"Hello world!",10,13,"$"