Improved countdown program in x86 NASM
•After I learned about macros, I started to use them a lot. Am I using them in place of headers (and is this bad), or is how I am using them fine?  

Looks OK to me.

•Am I over-using/misusing %defines (more specifically, KERNEL_CALL)?

I wouln't use KERNAL_CALL in stead of int 80h. The latter is shorter and the value involved will not change any soon in the future.

•Do I have too many or too few comments?  

I find commenting on .subtract: a bit stating the obvious.

•Are my comments unclear?

No, they are very readable.

•Are there any unnecessary lines? I'm a little worried about the popping at the end of put_num...

The popping at the end of put_num is correct (pushing/popping 2 words in a row nicely keeps the stack aligned at dwords) but a few lines seem unnecessary to me. You do not need to compare AX with 0 since subtracting already defines the flags.
You could also shave off an extra jump.

sub ax, 1;      subtract 1
cmp ax, 0;      compare ax with 0...
je .blast_off;  if equal, jump to .blast_off
jmp countdown;  if not equal, go back to countdown
.blast_off:


Better code:

sub ax,1
jnz countdown
.blast_off:


•Am I following convention, or are there more things I should do?

The ordering of the sections of the program is a matter of taste. But I see most people put the .data section before the .text section.

•Is my code understandable?

Very understandable.