JWasm: Difference between revisions
[unchecked revision] | [unchecked revision] |
Content deleted Content added
m Bot: Replace deprecated source tag with syntaxhighlight |
|||
(7 intermediate revisions by 4 users not shown) | |||
Line 1:
'''
==History==
==Usage==
===Abbreviated Notation===
<syntaxhighlight lang="asm">
mov eax, DWORD PTR [edi]
</syntaxhighlight>
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.
<syntaxhighlight lang="asm">
mov eax, [edi]
</syntaxhighlight>
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.
<syntaxhighlight lang="asm">
movzx eax,
movzx eax, BYTE PTR [esi] ; zero extend a BYTE into the 32 bit EAX register
</syntaxhighlight>
===OFFSET Operator===
For a corresponding data entry in the initialised data section,
<syntaxhighlight lang="asm">
textitem db "This is a text item",0
</syntaxhighlight>
This data entry can be addressed in the following manner.
<syntaxhighlight lang="asm">
mov eax,
</syntaxhighlight>
===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.
<syntaxhighlight lang="asm">
'''push arg3'''▼
</syntaxhighlight>
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 49 ⟶ 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:
<syntaxhighlight lang="asm">
</syntaxhighlight>
===Square Brackets===
There is some flexibility in how square brackets can be used in historical Intel notation compatible assemblers.
<syntaxhighlight lang="asm">
'''mov eax, [ecx+edx]'''▼
</syntaxhighlight>
Both notations are correct here and in the second example the extra pair of square brackets function as an ADDITION operator.
===Limited Type Checking===
Using an example prototype from the 32 bit Windows API function set,
<syntaxhighlight lang="asm">
SendMessage
SendMessage equ <SendMessageA>
</syntaxhighlight>
The code to call this function using the '''INVOKE''' notation is as follows.
<syntaxhighlight lang="asm">
</syntaxhighlight>
Which is translated exactly to,
<syntaxhighlight lang="asm">
'''push lParam'''▼
</syntaxhighlight>
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.
===Pseudo High Level Emulation===
It supports the '''.IF''' block structure,
<syntaxhighlight lang="asm">
; ...
; ...
; ...
</syntaxhighlight>
It also supports the '''.WHILE''' loop structure,
<syntaxhighlight lang="asm">
</syntaxhighlight>
And the '''.REPEAT''' loop structure.
<syntaxhighlight lang="asm">
.until eax < 1
</syntaxhighlight>
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.
The combined pseudo high level emulation allows
==Pre-processor==
The pre-processor in
At its simplest, a macro in
<syntaxhighlight lang="asm">
ItemName MACRO argument1, argument2, argument3:VARARG
mov argument1, argument2
mov argument3, argument1
ENDM
</syntaxhighlight>
This macro is called as follows,
<syntaxhighlight lang="asm">
ItemName eax, ecx, edx
</syntaxhighlight>
It is expanded by the pre-processor to,
<syntaxhighlight lang="asm">
mov eax, ecx
mov edx, eax
</syntaxhighlight>
==Licence==
*[http://www.japheth.de/JWasm/License.html JWasm License]
== External Links, Reference And Footnotes ==
*[http://www.japheth.de/JWasm.html JWasm Home (broken link)]
*[https://github.com/JWasm/JWasm JWasm on Github]
*[http://sourceforge.net/projects/jwasm/ JWasm project page on SourceForge]
*[http://www.masm32.com/board/index.php The MASM Forum]
|