Assembly Reference

Introduction


When I started OS development, I used NASM to compile simple assembly files to make the initial Hello World! tutorials, and it was a happy time.

As the kernel grew, and most of it migrated to C (compiled with GCC), I still did all the assembly coding is NASM and linked the resultant files in.

However, maintaining this extra binary dependency was problematic, especially when moving to an IDE such as NetBeans, so I decided to investigate moving all the assembly parts to GNU AS so that I could just use the GNU toolchain.

This page is to serve as a reference for the things that took far too long to track down / figure out / experimentally derive in the first place, so I've written them down for my future reference.

All code is intended for 32-bit protected mode.

Manuals

The manual is located here: http://sourceware.org/binutils/docs/as/
Another version is located at:  http://www.math.utah.edu/docs/info/as_toc.html#SEC6
I can kind of accept that GAS is intended to be used for a number of different architectures, so it's documentation doesn't serve as a comprehensive reference of 32-bit x86 assembly.

x86 Assembly Reference:  http://en.wikibooks.org/wiki/X86_Assembly
x86 Opcode Reference: http://ref.x86asm.net/coder-abc.html


Jumping 


Most boot-loaders will need to switch from 16-bit to 32-bit protected mode at some point, and to do so requires a "Far Jump" which sets the Code Segment (CS) register as well as the Instruction Pointer (EIP).  This jump is usually used to clear the CPU instruction pipeline which will have been filled with 32-bit instructions that the processor will have started to interpret as 16-bit instructions (so won't make sense).

NASM Syntax:   jmp 0x8:MyLabel
GAS Syntax:   ljmp $0x8, $MyLabel
-or-
  .byte 0xEA
  .long MyLabel
  .word 0x08


Pushing Constants


When you push an immediate (constant) value to the stack, you have to tell the processor how big the value is so that it knows how many bytes following the opcode that it should push.

NASM Syntax:   push byte 0x33
GAS Syntax:   push 0x33
-or-
  .byte 0x6A
  .byte 0x33

It appears as if GAS defaults to using byte-sized pushes for immediate values, and you use the pushw or pushl instruction to do anything else.  It's strange that pushb should give the error "Error: unsupported instruction `push'".







No comments:

Post a Comment