%macro print_ch 1 push ax push bx mov bx, 0x000F mov al, %1 mov ah, 0x0e int 0x10 pop bx pop ax %endmacro %macro cls 0 mov ax, 0x0600 ; AH=06 Scroll screen, AL=0 Clear screen mov bh, 0x0F ; black bg, white fg mov cx, 0x0000 ; x1=y1=0 mov dx, 0x5019 ; 89x25 int 0x10 ; Graphics services %endmacro ; bx = string to print print: pusha .loop: mov al, [bx] cmp al, 0 je .end ; go to end if char == 0 mov ah, 0x0e int 0x10 add bx, 1 jmp .loop ; loop .end: popa ret print_nl: pusha mov ax, 0x0e0a int 0x10 mov ax, 0x0e0d int 0x10 popa ret println: pusha call print mov ax, 0x0e0a int 0x10 mov ax, 0x0e0d int 0x10 popa ret print_hex_digit: pusha mov al, bl mov bl, 0x0F and al, bl ; Get rid of all but the last nibble ; If the value is >= 0xA, then we need to add to the alphabetical block of the ascii table cmp al, 0x0A jl .skip_alpha ; If the number is not at least 0xA, then skip this step add al, 0x07 ; 'A' == 0x41, '0' == 0x30, 0x41 - 0x30 == 0x11 ; Ignore ^^^^^^^ THIS ^^^^^^ actually. ; It works and i've not got a clue why. Oh well. Such is life. .skip_alpha: add al, 0x30 ; Add ASCII '0' push bx mov bx, 0x000F mov ah, 0x0e int 0x10 pop bx popa ret print_hex: pusha mov ax, bx shr bx, 12 call print_hex_digit mov bx, ax shr bx, 8 call print_hex_digit mov bx, ax shr bx, 4 call print_hex_digit mov bx, ax call print_hex_digit popa ret print_bin: pusha mov cx, 0 .loop: cmp cx, 16 je .end test bx, 0x8000 jnz .one push bx mov bl, 0x02 mov ah, 0x0e mov al, 0x30 int 0x10 pop bx jmp .continue .one: push bx mov bl, 0x03 mov ah, 0x0e mov al, 0x31 int 0x10 pop bx .continue: shl bx, 1 add cx, 1 jmp .loop .end: popa ret ; bx = number to print print_uint: pusha mov ax, bx ; Move number into ax mov bx, 0 .loop: mov cx, 10 mov dx, 0 ; IMPORTANT: Division will not work unless the higher register is in a usable length div cx ; Divide ax by cx (10), -> ax, rem -> dx add dx, 0x30 ; Add ascii '0' push dx ; Push that value add bx, 1 cmp ax, 0 ; Continue looping as long as the quotient is not 0 jnz .loop .print_loop: sub bx, 1 pop ax ; 16-bit value mov ah, 0x0e ;add al, 0x30 push bx mov bx, 0x000F int 0x10 pop bx cmp bx, 0 jnz .print_loop popa ret print_sint: pusha ; Old (non-working method) used a copy of above with idiv. I think this way is smarter test bx, 0x8000 ; Check sign-bit jz .positive print_ch '-' neg bx .positive: call print_uint popa ret