bits 16 cpu 8086 segment .text org 100h jmp demo ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Given a number in AX, return string with ordinal suffix ;; in DX. nth: mov cx,10 ; Divisor mov bx,.sfx ; Pointer to end of number .digit: xor dx,dx ; Zero DX div cx ; AX = DX:AX/10; DX=remainder add dl,'0' ; Make digit dec bx ; Back up the pointer mov [bx],dl ; Store digit and ax,ax ; Done yet? (AX=0?) jnz .digit ; If not, get next digit mov dx,bx ; Keep string pointer in DX xor bx,bx ; Default suffix is 'th'. cmp byte [.num+3],'1' ; Is the tens digit '1'? je .setsfx ; Then the suffix is 'th'. mov cl,[.num+4] ; Get the ones digit cmp cl,'4' ; Is it '4' or higher? jae .setsfx ; Then the suffix is 'th'. mov bl,cl sub bl,'0' ; Calculate offset. shl bl,1 ; [0..3]*2 + .ord .setsfx: mov ax,[bx+.ordsfx] ; Set suffix mov [.sfx],ax ret .ordsfx: db 'thstndrd' .num: db '*****' .sfx: db '**$' ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Print numbers. demo: mov ax,0 ; Starting at 0... mov bl,26 ; ...print 26 numbers [0..25] call printn mov ax,250 ; Starting at 250... mov bl,16 ; ...print 16 numbers [250..265] call printn mov ax,1000 ; Starting at 1000... mov bl,26 ; ...print 26 numbers [1000..1025] ;; Print BL numbers starting at AX printn: push ax ; Keep number push bx ; Keep counter call nth ; Get string for current AX mov ah,9 ; MS-DOS print string int 21h mov dl,' ' ; Separate numbers by spaces mov ah,2 ; MS-DOS print character int 21h pop bx ; Restore counter pop ax ; Restore number inc ax ; Next number dec bl ; Are we done yet? jnz printn ret