Gas Intel Howto

From OSDev Wiki

Jump to: navigation, search

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.

Personal tools