The "Go" tools
The GoAsm manual
for those new to ....
assembly language
by Jeremy Gordon -
If you have only previously tried
assembler in 16-bits and hated it - give it another try. Using assembler
in 32-bits, particularly in the Windows environment, is easy, clean and
fun!
What is assembly language?
Assembly language is a programming language. Programs are written in
text form using a text editor (to make "source code"). This source code
is read by the "Assembler" and the "Linker" to provide the final executable
program.
A feature of assembly language is that each line in the source code
usually contains a single instruction to the processor, for example MOV
EAX,EDX will move the content of the EDX register into the EAX register.
Here the "MOV" instruction is called a "mnemonic". This may seem a pretty
basic instruction if you are used only to a higher level language. However,
in Windows, you also have the use of a vast high level language (Windows
itself). Thus, using Windows and assembler gives you the benefit of both
a high level language and also control of the processor - perfect combination!
Why code at such a basic
level?
There are several reasons why you may wish to do this:
-
No bloat. By coding at this low level you can reduce the code to the minimum
required for the job in hand.
-
Speed. Smaller code size means your programs load quicker and run quicker.
-
Control. You are in control of the code, not the compiler. This means you
know exactly what the processor is doing as it moves through your code.
This makes it easier to get things right and to spot errors.
-
Satisfaction. You yourself are writing the program. It is not being written
in part by the compiler.
The coding components available
to you.
You will need to study the instructions which come with your assembler
for a full account of these. However, ignoring instructions which would
not be used in Windows, conditional assembly, macros, and the floating
point, MMX and 64 bit instructions, basically the components can be divided into
these categories:
-
Register instructions. This is where you tell the processor to move data
or carry out calculations using its own 32-bit registers. There are 6 such
registers for general use called EAX, EBX, ECX, EDX, ESI and EDI. Examples
of such instructions are:-
MOV ESI,EBX ;move contents of EBX register into ESI register
ADD EAX,EDI ;add contents of EDI register to EAX register
BT ECX,0 ;test bit 0 of ECX register
CMP EDX,450 ;compare contents of EDX with 450
DIV ECX ;divide EDX:EAX (long integer) by ECX
MUL ECX ;multiply EAX by ECX result in EDX:EAX (long integer)
SHL EDX,4 ;shift EDX bits to the left by 4 bits (multiply by 16)
TEST EAX,8 ;test bit 3 of EAX register
|
-
Stack instructions. The stack is an area of memory provided by Windows
for each running program to use as a temporary storage area. Examples of
such instructions are:-
PUSH EAX ;push the contents of EAX register onto the stack
POP EDX ;pop the last thing pushed on the stack to EDX
PUSH 1000h ;push hex value 1000 on the stack
MOV EBP,ESP ;keep current stack pointer in the EBP register
SUB ESP,30h ;move the stack pointer to make an area for local data
MOV D[EBP-20h],500h ;insert the value 500 hex in the local data area
|
- Execution instructions. These divert the processor to execute code from
a point other than the next line in the source code. Examples are:-
CALL MAKEWINDOW ;execute the procedure and return afterwards
CALL EAX ;execute from EAX code address and return afterwards
RET ;finish with this procedure returning to the caller
JZ 4 ;continue execution from label 4: if result was zero
JC >.fin ;continue execution from .fin if carry flag is set
JMP MAKEWINDOW ;continue execution from the named procedure
LOOP 2 ;decrement ECX and jump to label 2: unless ECX=0
|
- Memory instructions. These read to, or write from, areas of memory other
than the stack. Typically this memory may be in the executable's own data
section or it could be from memory allocated by Windows at run time.
Examples are:-
ADD EAX,[ESI] ;add to EAX contents of memory pointed to by ESI
MOV EAX,[MYDATA] ;move to EAX contents of memory at the MYDATA label
SUB D[MYDATA+64],10h ;subtract 10h at dword at MYDATA plus 64 bytes
CMP B[MYDATA+EDX*4],2 ;compare a byte with 2 in part of MYDATA array
LODSB ;load byte at memory pointed to by ESI into al
STOSD ;load the contents of EAX into memory pointed to by EDI
|
- Flag instructions. The main flags you will use are Z (zero flag), C (carry
flag), S (sign flag) and D (direction flag). Most instructions change the
flags automatically to give the result of the instruction. There are certain
specific instructions you can use to change the processor flags manually:-
STC ;set the carry flag
CLC ;clear carry flag
STD ;set the direction flag for LODS,
;STOS, CMPS, SCAS, MOVS
CLD ;clear direction flag
|
- Declarations of memory. Windows reserves memory for the executable when
it runs. Declarations are made to reserve memory in the data section
or constant section if the data is to be initialised that is,
set to a value. If the data does not have to be initialised the data area
can be reserved in the unitialised data section. This does not take
up any space in the Exe file. Instead space in memory is allocated for this
type of data when the executable first starts.
Examples of how memory is declared is as follows (some of these differ
between Assemblers):-
DB 4 ;declare a byte and set to initial value 4
MYDATA DB 4 ;a byte initial value 4 with data label MYDATA
MYSTRUCT DD 16 DUP 0 ;16 dwords all set to zero called MYSTRUCT
BUFFER DB 1024 DUP ? ;1024 bytes called BUFFER in undefined data
|
- Instructions to tell the Assembler into which section to put the following
source code. The Assembler marks the code section as read-only and executable,
and defined and undefined data sections as read/write.
Here are examples (this will differ between Assemblers):-
CODE SECTION ;all following to be in a section to be marked
;as read-only and executable (code)
DATA SECTION ;all following to be in a section with read/write
;attributes but not code attributes
CONST SECTION ;all following to be in a section with read
;attributes only
|
- Comments. Everything after a semi-colon will be ignored, enabling you to
describe exactly what your source code is doing and why.
- Windows instructions. This gives the assembler programmer access to the
vast range of Windows APIs (Applications Programming Interface). This is
code within the Windows operating system. Examples are:-
PUSH 12h ;push hex value 12 onto stack for API call
CALL GetKeyState ;ask Windows to get state of Alt key in EAX
TEST EAX,80000000h ;test whether Alt key is pressed (bit 31 set)
JZ >L22 ;no, jump forward to L22
.............
PUSH 24h ;hex value 24 = question mark, yes and no button
PUSH ESI,EDI ;address of title, address of message
PUSH [hWnd] ;owner's window handle
CALL MessageBoxA ;show Windows message box asking yes/no
CMP AL,7 ;see if "no" was clicked by the user
JNZ >L40 ;no, jump forward to L40
.............
PUSH 0
PUSH ADDR FILE_DONE ;give address of FILE_DONE to receive result
PUSH ECX,EDX ;ECX=bytes to write, EDX=source of data,
PUSH ESI ;ESI=file handle
CALL WriteFile ;write ECX bytes from EDX to ESI
.............
PUSH 808h,5h ;808=bottom and filled middle, 5=raised
PUSH EBX,EDX ;ebx=RECT, EDX=device context
CALL DrawEdge ;draw special edged rectangle to screen
.............
PUSH 4h,3000h,ESI,0 ;4h=make read/write memory, 3000h=reserve
CALL VirtualAlloc ;reserve and commit ESI bytes of read/write memory
.............
PUSH 0,[hInst],0,0 ;param, module handle, menu, owner
PUSH 208,130,30,300 ;height, width, y, x
PUSH 80C80000h ;style (POPUP+CAPTION+SYSMENU)
PUSH EAX ;EAX=address of zero terminated string with title
PUSH 'LISTBOX' ;push pointer to 'LISTBOX'
PUSH 0 ;extended style (none)
CALL CreateWindowExA ;create listbox window
...... or if you prefer, you can use INVOKE ..
INVOKE CreateWindowExA, 0,'LISTBOX',EAX,80C80000h,300,30,130,208 \
0,0,[hInst],0
.............
INVOKE ShowWindow, [hWnd], 1
|
Copyright © Jeremy Gordon 2002-2003
Back to top
|