Gas Intel Howto
This is a copy of MirBSD's gas-intel-howto (v1.2), Wikified from the groff source.
- Copyright (c) 2004 Thorsten "mirabile" Glaser <>
- Licensee is hereby permitted to deal in this work without restriction, including unlimited rights to use, publicly perform, modify, merge, distribute, sell, give away or sublicence, provided all copyright notices above, these terms and the disclaimer are retained in all redistributions or reproduced in accompanying documentation or other materials provided with binary redistributions.
- Licensor hereby provides this work "AS IS" and WITHOUT WARRANTY of any kind, expressed or implied, to the maximum extent permitted by applicable law, but with the warranty of being written without malicious intent or gross negligence; in no event shall licensor, an author or contributor be held liable for any damage, direct, indirect or other, however caused, arising in any way out of the usage of this work, even if advised of the possibility of such damage.
Hopefully, this small tutorial takes away the fear from both UNIX(R) programmers coming from GAS AT&T move, and PC programmers from NASM.
How to write Intel syntax assembly code with the GNU assembler
Did you always wonder how this new Intel mode of as(1) could be used? Did you wonder why the GNU Texinfo documentation is wrong? This is the answer.
First off, how would you start an assembly language programme? This is a real-life example:
/* copyright ... */ #include <machine/asm.h> .intel_syntax noprefix .text
Now, you can use all the well-known ops and pseudo-ops from the gas and intel world. You just need to keep track, which one to use.
Did you know you can concatenate assembly lines with a semicolon (';')?
Now, how do you issue comments? It's easy. Using gcc -c -o fnord.o fnord.S automatically uses the C Preprocessor, cpp(1), on the file first. That's why the C-style comment in the above example could be used.
All these pseudo-ops, and more, are supported on ELF:
Denotes a code segment.
Denotes the data segment.
Denotes reserved space.
Generate code for a 32-bit segment (default).
Generate code for a 16-bit segment.
This defines a global symbol.
For ELF you apparently also need:
.type symbol, @function
This denotes the ELF symbol type. You'd better use the ENTRY(symbol) macro though.
.byte .word .long
Define bytes (etc.), akin the db command in TASM.
Define a string, also the same as the db command.
Define a zero-terminated string.
There needs not be extra .byte 0x0A commands for control characters; rather use C escapes like this:
.data foo: .asciz "Hello, World!\n" .text bar: mov eax,offset foo push eax call printf pop eax ret
This is similar to NASM's backquote (`) feature to allow C escapes to be translated to the appropriate db's during assemble-time.
This example also shows the basic command usage. Some commands are different from both Intel common and the gas intel mode texinfo documentation.
Used exactly as the retf command.
mov byte ptr ~[bx],0x80
The byte ptr is a must.
This is the way long jumps (jmp far) are defined. The manual states one has to use jmpl or ljmp.
. = 0x40 + _start
The org directive refined. Better than in NASM. It also is a good way to check code size boundaries.
Just write them one after the other.
fs mov eax,~
This is a segment prefix usage. Note, here is no dword ptr needed.
It's not difficult to write intel code in GNU as, once you have learned about the differences. In fact, it is even more consistent than for example NASM, which insists on calling pushf pushfw, and issues a pushfd when writing pushf in 32-bit mode.
Copyright (c) 2004 Thorsten Glaser. All rights reserved.
Credits go to Intel, AMD, Microsoft, Borland, the NASM and YASM projects and the Free Software Foundation.
Probably some typos and omissions. Also, my nroff isn't the best.
Suggestions to <> please.