Here's an x86 asm program which prints a 'counter' from 000 to 999 in the middle of the screen which works fine (I didn't write it). The issue is I'm trying to understand how it works. What the use of DIV
and the STACK are in THIS program.
How will the program know how to go e.g. from 009 to 010. What's the inner loop?
I know how it clears the screen and prints to the middle of the screen and I know about the clock delay function.
What purpose do DIV
, PUSH
, and POP
serve in this program?
Basically I'm trying to trace it and understand the functions used. I'm still quite a beginner, please help. Thanks.
Here's the code:
.MODEL SMALL
.STACK 64
.DATA
CNT DW 0h
.CODE
MOV AX,@data
MOV DS,AX
MOV AX, 0600H
MOV BH,07
MOV CX, 0000
MOV DH,12
MOV DL,39
INT 10H
MOV AX,0600H
MOV BH,07
MOV CX,0000
MOV DX,184FH
INT 10H
MOV CNT,0
L1: MOV AH,02h
MOV BH,0
MOV DH,12
MOV DL,39
INT 10h
MOV AX,CNT
MOV BL,10
DIV BL
PUSH AX
MOV AH,00
MOV BL,10
DIV BL
PUSH AX
MOV DL,AL
ADD DL,48
MOV AH,02h
INT 21h
POP AX
MOV DL,AH
ADD DL,48
MOV AH,02h
INT 21h
POP AX
MOV DL,AH
ADD DL,48
MOV AH,02h
INT 21h
MOV CX, 0007h
MOV DX, 2120h
MOV AH, 86H
INT 15H
INC CNT
CMP CNT,999
JBE L1
MOV AH,4ch
INT 21h
END
How will the program know how to go e.g. from 009 to 010, what's the inner loop ?
The inner loop is formed from the L1
label to the JBE L1
instruction. The memory CNT
holds the counter that is being displayed. It is initialized to zero from the executable and is incremented (INC CNT
), compared to 999 and loop while it is below or equal.
What purpose does DIV, PUSH and POP serve in this program ?
The purpose is to split up the CNT
value into separate digits and display them. DIV BL
divides AX
by BL
and stores the quotient in AL
and remainder in AH
.
Perhaps the best explanation of what this is doing is through an example. Suppose, CNT
had a value of 123. To compute each printable digit, we would divide by 10 and get a quotient of 12 with a remainder of 3. Now, 3 is what we need to print last so we need to store that in the stack. Then we would repeat this process getting 2 and then 1. Now, we can print out 1, pop out the 2 in the stack and print that and then pop out the 3 and print that so we have 123 printed out.
The code segment
MOV DL,AH
ADD DL,48
MOV AH,02h
INT 21h
is responsible for printing each digit. It first gets the remainder which was stored in AH
, add 48 (030h) to get the ASCII digit ('0' = 30h .. '9' = 39h) and then calls function 02h/int21 to print a single character to the screen.