I'm using NASM 16 BITS. I'm trying to do a simple assembly code that prints the numbers from 0 to 255 with 1 second interval between each number. This is what I have so far:
[bits 16]
mov ax,cs
mov ds,ax
mov cx,255
mov ax,0
myloop:
;print in screen ax value
;wait 1 second
inc ax
loop myloop
I'm not sure how to print the value of ax in the screen, and how to wait 1 second(placed them in a comment in the code).
There's a 4-byte counter at segment 0 offset 46Ch (or alternatively at seg 40h, offs 6Ch) maintained and updated by the PC BIOS. It's incremented 18.2 times per second. Counting 18 changes in the lowest byte or word of this counter is probably the simplest way of waiting out approximately a second:
To print decimal numbers you need to convert binary numbers into decimal, get individual digits and print them. You divide the number by 10 and collect remainders. e.g.:
123:
123 / 10: quotient 12, remainder 3
12 / 10: quotient 1, remainder 2
1 / 10: quotient 0, remainder 1
By repeatedly dividing by 10 you get the individual digits in the remainders in the reverse order: 3,2,1. Then you print them using DOS int 21h function 2 (load 2 into
AH
, load the character's ASCII code intoDL
, executeint 21h
).An alternative variant, quite suited to your problem, would be to use the
DAA
instruction to increment the number directly in decimal without any conversion.Here's how it all can be done:
If you don't like the leading zeroes or the last 1-second delay, you can conditionally skip them.
Download Intel and/or AMD x86 CPU manuals that describe how each instruction works. Read them. Also, download the
Ralf Brown's Interrupt List
, which describes every BIOS and DOS function. You need to know some of them to do I/O. There are alsoHelpPC
andTechHelp
that conveniently describe many BIOS and DOS things like theBIOS Data Area
where the aforementioned counter lives.