====== Writing assembly ====== In the Wonderful toolchain, assembly files use the ''.s'' extension. They are compiled using the GNU assembler and the C preprocessor. ===== Creating an assembly file ===== It is recommended to start with a preamble similar to the following: #include // (1)! #include // (2)! .code16 // (3)! .arch i186 // (4)! .intel_syntax noprefix // (5)! - Include the Wonderful toolchain's basic definitions. This provides some useful assembly defines and macros. - Include the libws library's definitions. This library supports being included in an assembler, and provides hardware-related defines - such as I/O port names and masks. - Tell the assembler to emit 16-bit code; this is useful as the GNU assembler supports all kinds of x86 code, including 32-bit and 64-bit. - Tell the assembler to emit 80186 code; this unlocks some additional 80186-exclusive opcodes supported on the NEC V30MZ. - Tell the assembler to emit Intel-syntax assembly; this is entirely optional, but the examples for external assembly files in this guide all make use of the Intel syntax, as opposed to the default AT&T syntax used in inline assembly. Note that to export a symbol (make it visible outside of the specific file, or translation unit), you need to use ''.global'', like so: .global strlen strlen: ===== Useful macros ===== ''wonderful.h'' provides some useful macros: * **WF_PLATFORM_CALL** - for portability between code models, you can use this macro in place of the ''call'' instruction to call C functions. * **WF_PLATFORM_JMP** - for portability between code models, you can use this macro in place of the ''jmp'' instruction to jump to C functions. * **WF_PLATFORM_RET** - for portability between code models, you can use this macro in place of the ''ret'' isntruction to return from a C-called function. * **WF_PLATFORM_CALL_STACK_OFFSET(x)** - for portability between code models, you can use this macro to get a stack offset with the function return address accounted for. For exapmle, in a "near" code model, ''WF_PLATFORM_CALL_STACK_OFFSET(10)'' returns ''12'', but in a "far" code model, it returns ''14''.