Here are some codes taken from "Exagone's Mosaic Tutorial" which I didn't understand.
Please anyone explain to me. My problem is I can't figure out what whole of the algo
is actually doing.

The comments below are made by Exagone himself.
;================================================================================
; --- Loop through all the numbers and draw them one by one ---
	xor		ebx, ebx
	.WHILE	ebx<16
		mov	eax, ebx
		inc	eax
		invoke	GetCoordinates, eax
		mov	dx, ax		; dx  = row
		shr	eax, 16 	; ax  = column
		and	edx, 0ffffh	; make sure that edx = dx
		imul	edx, edx, 50;} Multipy edx as well as eax with 50
		imul	eax, 50		;} 
		mov	TempRect.left, eax
		mov	TempRect.top, edx
		add	eax, 50
		add	edx, 50
		mov	TempRect.right, eax
		mov	TempRect.bottom, edx
		mov	eax, ebx
		inc	eax
		invoke	wsprintf, ADDR Buffer, ADDR NumberFormat, eax
		invoke	DrawText, ImageDC, ADDR Buffer, -1, ADDR TempRect,\
				DT_CENTER or DT_SINGLELINE or DT_VCENTER
	inc ebx
	.ENDW
ret
DrawNumbers endp
;================================================================================
;				GetCoordinates
;================================================================================
GetCoordinates proc	dwTile:DWORD
	mov	eax, dwTile
	dec	eax
	cdq
	mov	ecx, 4
	div	ecx
	;eax=quotient = row
	;edx=remainder = column
	shl 	edx, 16
	add	eax, edx
ret
GetCoordinates endp
;================================================================================
;================================================================================

Well this is the whole algo. Now I will try to explain what I have understood.
MY DOS BASED ASM IS VERY POOR which you'll see in few seconds.

The comments below are made by myself.
;================================================================================
; --- Loop through all the numbers and draw them one by one ---
	xor		ebx, ebx	;clear EBX
	.WHILE	ebx<16			;loop until EBX is less than 16
		mov	eax, ebx	;since EBX==0 now EAX==0
		inc	eax		;EAX is now 1
		invoke	GetCoordinates, eax	;call the subroutine
		mov	dx, ax		;dx = row	;don't know how
		shr	eax, 16		;ax = column	;don't know how
		and	edx, 0ffffh	;make sure that edx = dx ==>WHY?
				    	;Why EDX must be equal to DX?
		imul	edx, edx, 50 	;} Multipy edx as well as eax with 50
				     	;Why multiply by 50 and what it is doing.
				     	;I mean why double EDX
		imul	eax, 50		;} same question why multiply by 50?
		mov	TempRect.left, eax	;mov the value in EAX to TempRect.left
		mov	TempRect.top, edx	;same thing	
		add	eax, 50		;I know what it is doing
					;EAX==EAX+50
					;but what it is adding 50 to EAX	
		add	edx, 50		;same thing here
		mov	TempRect.right, eax	;moving the value of EAX
		mov	TempRect.bottom, edx	;moving the value of EDX
		mov	eax, ebx	;EAX==EAX+EBX==0
		inc	eax		;EAX==0
		invoke	wsprintf, ADDR Buffer, ADDR NumberFormat, eax
		invoke	DrawText, ImageDC, ADDR Buffer, -1, ADDR TempRect,\
				DT_CENTER or DT_SINGLELINE or DT_VCENTER
	inc ebx		;EBX is now 1
	.ENDW		;end the loop is EBX<16
ret			;return
DrawNumbers endp
;================================================================================
;				GetCoordinates
;================================================================================
GetCoordinates proc	dwTile:DWORD
	mov	eax, dwTile	;mov dwTile to EAX. If dwTile is moved to EAX
				;then what exactly EAX is holding? is it the address.
	dec	eax		;don't know what is doing?
	cdq			;?????
	mov	ecx, 4		;ECX==4
	div	ecx		;divide ECX by EAX and the remainder is in EDX
				;eax=quotient = row (how EAX will contain the number of
				;row)
				;edx=remainder = column (how EDX will contain the number
				;of column
	shl 	edx, 16		;shift EDX by 16. I think it puts zeroes.
	add	eax, edx	;EAX==EAX+EDX
ret
GetCoordinates endp
;================================================================================
;================================================================================
Can't do better formating than this!
Posted on 2001-05-03 11:37:00 by e-nigma
I'll explain it here (btw if you didn't know, I'm exagone): The tiles are counted from 0 to 15 (ebx is the counter). For some functions like GetCoordinates, the tiles are counted from 1 to 16. GetCoordinates takes such a count (0-16) as a parameter and then returns the 'tile coordinates', i.e. the row and column of the tile into the lower and higher words of eax.

Tile numbers (the counter uses)
Table1: 
 0   1   2   3
 4   5   6   7
 8   9   10  11
 12  13  14  15
Tile numbers (GetCoordinates uses)
Table2: 
 1   2   3   4
 5   6   7   8
 9   10  11  12
 13  14  15  16

Now here are the coordinates in (column, row) format:
Table3:
 (0,0) (1,0) (2,0) (3,0)
 (0,1) (1,1) (2,1) (3,1)
 (0,2) (1,2) (2,2) (3,2)
 (0,3) (1,3) (2,3) (3,3)
Getcoordinates takes a tile by the numbers in table 2 above, translates it to the numbering in table 1, then converts it to a coordinate like table3. It does this by dividing the tile numbers according to table1 by 4. The remainder of this calculation is the column, the quotient will be the row.

GetCoordinates proc   dwTile:DWORD
   mov   eax, dwTile   
   ;eax is now a tile number, counted from 1 to 16 !!!! 

   dec   eax 
   ;eax is decreased by one, to translate the count from 1 to 16, to the count from 0 to 15.

   cdq      
   ;cdq extends eax to edx:eax. This is necessairy as the div opcode divides edx:eax, not only eax

   mov   ecx, 4
   div   ecx  ;divide by 4
   ;now eax (the quotient) contains the row
   ;edx (the remainder) contains the column

   shl   edx, 16    
   ;this shifts the value of edx (the column) to the higher word of edx.

   add   eax, edx   ;the column in the high word of edx is added to the row in the low word in eax
ret
GetCoordinates endp
The drawing loop takes the (column, row) coordinates and then determines where the tile should be drawn like this: tile.leftcoordinate = column * 50 tile.rightcoordinate = column * 50 + 50 tile.topcoordinate = row * 50 tile.bottomcoordinate = row * 50 + 50 The 50 is the size of the tiles, the tiles are 50x50 pixels and logically positioned at coordinates that are multiples of 50 pixels. O I forgot, this code:

mov   dx, ax      ;dx = row
shr   eax, 16      ;ax = column
and   edx, 0ffffh  ;make sure that edx = dx
Before this code, eax contains the column in the high word of eax, and the row in the lower word. mov dx, ax moves the lower word (ax) of eax into the lower word (dx) of edx. Then the high word of eax is shifted into the low word (shr eax, 16) and because the high word of edx is not touched, it can have any value. Therefore, edx is AND-ed with 0ffffh, leaving only the low word in edx (edx=dx). now eax contains the column, and edx contains the row. I hope you understand it now. Thomas This message was edited by Thomas, on 5/3/2001 12:36:35 PM
Posted on 2001-05-03 12:32:00 by Thomas
Thanks Thomas. Now I'll read futher.
Posted on 2001-05-05 02:14:00 by e-nigma