4. Debugging your code

First, you must enable debugging information by setting DEBUG = y in MCONFIG. Then rebuild your code, and try one of the available debuggers:

4.1. ald

There's the Assembly Language Debugger, which is designed to work with assembly code, and is portable enough to run on Linux and *BSD. It is already functional and should be the right choice, check it out!

4.2. gdb

Although gdb is source-level debugger, it can be used to debug pure assembly code (the simplest way is to place int 3 instructions as breakpoints across your code). And with some trickery you can force gdb to do what you need (unfortunately nasm '-g' switch does not generate proper debug info for gdb yet):

Using GDB with asmutils (by Dmitry Bakhvalov)
--------------------------------------------

Personally, I use gdb for debugging asmutils. Try this:
 
1) Use the following stuff to compile:
   $ nasm -f elf -g smth.asm
   $ ld -o smth smth.o

2) Fire up gdb:
   $ gdb smth

3) In gdb:
   (gdb) disassemble _start
   Place a breakpoint at <_start+1> (If placed at _start the breakpoint
   wouldn't work, dunno why)
   (gdb) b *0x8048075

   To step thru the code I use the following macro:
   (gdb)define n
   >ni
   >printf "eax=%x ebx=%x ...etc...",$eax,$ebx,...etc...
   >disassemble $pc $pc+15
   >end

   Then start the program with r command and debug with n.

   Hope this helps.

An additional note from ???
---------------------------

    I have such a macro in my .gdbinit for quite some time now, and it
    for sure makes life easier. A small difference : I use "x /8i $pc",
    which guarantee a fixed number of disassembled instructions. Then,
    with a well chosen size for my xterm, gdb output looks like it is
    refreshed, and not scrolling.

4.3. strace

Definitely strace can help a lot (ktrace and kdump on FreeBSD), it is used to trace system calls and signals. Read its manual page (man strace) and strace --help output for details.