JWasm: Difference between revisions

[unchecked revision][unchecked revision]
Content deleted Content added
No edit summary
m Bot: Replace deprecated source tag with syntaxhighlight
 
(One intermediate revision by the same user not shown)
Line 10:
This notation is a fully specified format which occurs in the following form:
 
<sourcesyntaxhighlight lang="asm">
mov eax, DWORD PTR [edi]
</syntaxhighlight>
</source>
 
Over time, the parsers in assemblers have improved to the stage where if the assembler can recognize the size of the data then the SIZE specifier may be omitted as such.
 
<sourcesyntaxhighlight lang="asm">
mov eax, [edi]
</syntaxhighlight>
</source>
 
This allows for clearer code that is easier to read. However, there are some contexts where the assembler cannot independently determine the data size; For example, if the source operand is a memory operand. In this situation the historical data SIZE specifiers must be used. The following is an example of this situation.
 
<sourcesyntaxhighlight lang="asm">
movzx eax, [esi] ; generates an error - data SIZE cannot be determined by the assembler
movzx eax, BYTE PTR [esi] ; zero extend a BYTE into the 32 bit EAX register
</syntaxhighlight>
</source>
 
===OFFSET Operator===
Line 32:
For a corresponding data entry in the initialised data section,
 
<sourcesyntaxhighlight lang="asm">
textitem db "This is a text item",0
</syntaxhighlight>
</source>
 
This data entry can be addressed in the following manner.
 
<sourcesyntaxhighlight lang="asm">
mov eax, OFFSET textitem
</syntaxhighlight>
</source>
 
===Transient Stack Addressing===
Operating systems provide memory for the area of memory referred to as the stack. Under x86 hardware, the stack is the main method of transferring arguments to procedures. Arguments are normally placed on the stack by the PUSH mnemonic in the following form. This example assumes the '''STDCALL''' calling convention and 32 bit data size.
 
<sourcesyntaxhighlight lang="asm">
push arg3
push arg2
push arg1
call FunctionName
</syntaxhighlight>
</source>
 
The CALL mnemonic pushed the return address onto the stack then branches to the address of the named procedure. If the procedure has a stack frame where the stack pointer register '''ESP''' is stored in the base pointer register '''EBP''' the first argument for the procedure occurs at address [ebp+8]. While this form of mnemonic notation can be written by experienced assembler programmers, the assembler provides a naming method to remove an un-necessary level of abstraction from writing code of this type.
Line 56:
The programmer can use the '''name''' of the argument in the place of the direct [EBP+displacement] notation to make the code more readable with no loss of performance. When the programmer needs to use the ADDRESS of a transient stack variable (normally referred to as a '''LOCAL''' variable) they have a number of methods. In a prototyped function call they can use the '''ADDR''' operator to obtain the address of a '''LOCAL''' variable. Alternatively they can use the direct Intel mnemonic '''LEA''' to load the effective address of the variable into a register:
 
<sourcesyntaxhighlight lang="asm">
lea eax, named_local_variable
</syntaxhighlight>
</source>
 
===Square Brackets===
Line 65:
There is some flexibility in how square brackets can be used in historical Intel notation compatible assemblers.
 
<sourcesyntaxhighlight lang="asm">
mov eax, [ecx+edx]
mov eax, [ecx][edx]
</syntaxhighlight>
</source>
 
Both notations are correct here and in the second example the extra pair of square brackets function as an ADDITION operator.
Line 77:
Using an example prototype from the 32 bit Windows API function set,
 
<sourcesyntaxhighlight lang="asm">
SendMessage PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
SendMessage equ <SendMessageA>
</syntaxhighlight>
</source>
 
The code to call this function using the '''INVOKE''' notation is as follows.
 
<sourcesyntaxhighlight lang="asm">
invoke SendMessage,hWin,WM_COMMAND,wParam,lParam
</syntaxhighlight>
</source>
 
Which is translated exactly to,
 
<sourcesyntaxhighlight lang="asm">
push lParam
push wParam
Line 96:
push hWin
call SendMessage
</syntaxhighlight>
</source>
 
The advantage of the '''INVOKE''' method is that it tests the size of the data types and the argument count and generates an assembly time error if the arguments do not match the prototype.
Line 104:
It supports the '''.IF''' block structure,
 
<sourcesyntaxhighlight lang="asm">
.if
; ...
Line 112:
; ...
.endif
</syntaxhighlight>
</source>
 
It also supports the '''.WHILE''' loop structure,
 
<sourcesyntaxhighlight lang="asm">
.while eax > 0
sub eax, 1
.endw
</syntaxhighlight>
</source>
 
And the '''.REPEAT''' loop structure.
 
<sourcesyntaxhighlight lang="asm">
.repeat
sub eax, 1
.until eax < 1
</syntaxhighlight>
</source>
 
The high level emulation also supports C runtime comparison operators that work according to the same rules as Intel mnemonic comparisons. For the .IF block notation the distinction between SIGNED and UNSIGNED data is handles with a minor data type notation variation where the storage size '''DWORD''' which is by default UNSIGNED can also be specified as '''SDWORD''' for SIGNED comparison. This data type distinction is only appropriate for the pseudo high level notation as it is unused at the mnemonic level of code where the distinction is determined by the range of conditional evaluation techniques available in the Intel mnemonics.
Line 139:
At its simplest, a macro in JWasm is constructed as follows:
 
<sourcesyntaxhighlight lang="asm">
ItemName MACRO argument1, argument2, argument3:VARARG
mov argument1, argument2
mov argument3, argument1
ENDM
</syntaxhighlight>
</source>
 
This macro is called as follows,
 
<sourcesyntaxhighlight lang="asm">
ItemName eax, ecx, edx
</syntaxhighlight>
</source>
 
It is expanded by the pre-processor to,
 
<sourcesyntaxhighlight lang="asm">
mov eax, ecx
mov edx, eax
</syntaxhighlight>
</source>
 
==Licence==