What's this supposed to do?
%define ascii(register)
I guess you want it to print a "1", a "0", and another "0". Since you haven't %defined it "as" anything, I would expect it to do nothing, and your code to print a 'd'. Lemme try it... Yeah.
Maybe what you're looking for is printf()... or maybe itoa(). We can show you how to "just call printf", but it sounds like you want to "do it yourself". The way (one way) to do that is to divide the value repeatedly by ten. Each time, we get the quotient in eax and the remainder in edx. It is the remainders we're interested in. We need to add '0' to each to convert the value to the ascii character representing that value (this is the character '0', not the number 0!). Unfortunately, we get the digits in the "wrong order" - we want to print '1' first, but we get it last. There are different ways to deal with that. A simple way, but not particularly "good" is to push 'em on the stack as we get 'em (when the quotient become zero, we're done) - then pop 'em off and put 'em in our buffer to print (or print 'em one at a time - even worse). Or we could put 'em in the buffer as we get 'em and do a "string reverse" at the end. Or we could start at the "end" of the buffer and work "backwards" towards the beginning. We probably won't make it all the way to the start of the buffer - we could, if we wanted to, pad the rest of the buffer with spaces (or zeros) - this looks nice for printing a column of numbers. Try it different ways if you're looking for exercises.
Besides being slow, the "div" instruction is a little tricky. It has a couple of "hidden" operands, and they depend on the one operand we provide! "div bl" divides ax by bl, quotient in al and remainder in ah. "div bx" divides dx:ax by bx, quotient in ax, remainder in dx. "div ebx" divides edx:eax by ebx, quotient in eax, remainder in edx. This is almost certainly the one we want. Notice that in each case the remainder "trashes" one of the "hidden" input registers! Failing to account for this is probably the most common newbie error of all time. If edx is bigger than ebx (or other register/memory we provide) the quotient won't fit in the register provided. This causes a "divide overfow error" - but DOS reported "divide by zero error" and Linux reports "floating point error". The remainder itself won't cause this, but we're going to add '0'... If we do this and then "div" again we crash and get an unhelpful error message.
Here's a starter...
section .bss
x resd 1
; big enough for "100" but a full
; 32-bit number can take up to
; 10 digits - plus you might want
; a terminating zero, perhaps a
; '+' or "-" sign...
; 16 is a nice round number
section .text
global _start
;macro with the linux system call
%macro print32b 1
mov eax, 4 ; sys_write
mov ebx, 1 ; stdout
mov ecx, %1 ; buffer
mov edx, 4 ;size of 32 bits
; more than enough for "100"
; not enough for "1000000000"
int 80h
%endmacro
%define ascii(register)
; you could make this a macro
; but I don't think you can do
; it as a single-line macro
_start:
mov eax, 100
; ascii(eax)
; mov [ x ], eax
mov ebx, 10 ; to divide by
xor ecx, ecx ; make digit counter zero
pushloop:
xor edx, edx
div ebx
push edx
inc ecx
cmp eax, 0
jnz pushloop
; we've got 'em, put 'em in the buffer
mov esi, x
poploop:
pop edx
add edx, '0'
mov [esi], dl
inc esi
loop poploop
; throw in a linefeed? just for looks?
mov [esi], byte 10
print32b x
mov eax, 1 ; sys_exit
mov ebx, 0 ; exit code
int 80h
Have fun!
Best,
Frank