Inline x86 ASM
Introduction
PureBasic allows you to include any x86 assembler commands (including MMX and FPU one) directly in the source code, as if it was a real assembler. And it gives you even more: you can use directly any variables or pointers in the assembler keywords, you can put any ASM commands on the same line, ... The syntax is the FAsm (http://flatassembler.net) one, so if you want more informations about the ASM syntax, just read the FAsm guide.
Rules
You have several rules to closely follow if you want to include asm in a Basic code :
- The used variables or pointers must be declared before to use them in an assembler keyword
- When you reference a label, you must put the prefix 'l_' before the name. This is because PureBasic add a 'l_' before a BASIC label to avoid conflit with internal labels. The label need to be referenced in lowercase when using the inlined ASM.Example:
MOV ebx,l_mylabel ... MyLabel:- The errors in an asm part are not reported by PureBasic but by FAsm. Just check your code if a such error happen.
- With enabled InlineASM you can't use ASM keywords as label names in your source.
- The available volatile registers are: eax, edx and ecx. All others must be always preserved.
- An ASM helpfile could be downloaded here. If you place the 'ASM.HLP' in the 'Help/' folder of PureBasic, you can also get help on Asm keywords with F1. (Note: this feature is only enabled, when InlineASM is enabled).
When using assembler in a procedure, you have to be aware of several important things:
- To return directly the 'eax' register content, just use 'ProcedureReturn', without any expression. It will let the eax register content untouched and use it as return value.Example:
Procedure.l MyTest() MOV eax, 45 ProcedureReturn ; The returned value will be 45 EndProcedure- Local variables in PureBasic are directly indexed by the stack pointer, which means than if the stack pointer change via an ASM instruction (like PUSH, POP etc..) the variable index will be wrong and direct variable reference won't work anymore.
- It's possible to pass directly an assembly line to the assembler without being processed by the compiler by using the '!' character at the line start. This allow to have a full access to the assembler directives. When using this, it's possible to reference the local variables using the notation 'p.v_variablename' for a regular variable or 'p.p_variablename' for a pointerExample:
Procedure Test(*Pointer, Variable) ! MOV dword [p.p_Pointer], 20 ! MOV dword [p.v_Variable], 30 Debug *Pointer Debug Variable EndProcedure Test(0, 0)Example
AsmInline.pb