Gas Intel Howto
From OSDev Wiki
This is a copy of MirBSD's gas-intel-howto (v1.2), Wikified from the groff source.
- Copyright (c) 2004 Thorsten "mirabile" Glaser <[1]>
- 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.
Contents |
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.
Pseudo-Ops
All these pseudo-ops, and more, are supported on ELF:
.text
Denotes a code segment.
.data
Denotes the data segment.
.bss
Denotes reserved space.
.code32
Generate code for a 32-bit segment (default).
.code16
Generate code for a 16-bit segment.
.globl symbol
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.
.ascii "foo"
Define a string, also the same as the db command.
.asciz "foo":
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
Operations
This example also shows the basic command usage. Some commands are different from both Intel common and the gas intel mode texinfo documentation.
lret
Used exactly as the retf command.
mov byte ptr ~[bx],0x80
The byte ptr is a must.
jmp 0xF000,0xFFF0
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.
rep movsd
Just write them one after the other.
fs mov eax,~[0]
This is a segment prefix usage. Note, here is no dword ptr needed.
Conclusion
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.
Acknowledgements
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.
Bugs
Probably some typos and omissions. Also, my nroff isn't the best.
Suggestions to <[2]> please.
