section .bss printr: .ax: resw 1 .cx: resw 1 .dx: resw 1 .bx: resw 1 section .text ; Stack contents ; ret-addr arg1 arg2 arg3 ... printf: mov [printr.ax], ax mov [printr.cx], cx mov [printr.dx], dx mov [printr.bx], bx pop bx .loop: mov al, [cs:bx] inc bx cmp al, 0 je .end cmp al, 2 je .word call pputc jmp .loop .end: push bx mov ax, [printr.ax] mov cx, [printr.cx] mov dx, [printr.dx] mov bx, [printr.bx] ret .word: pop dx call pdx jmp printf.loop pdx: ; this double-call is essentially a 4 times repeating loop call .l1 .l1: call .l2 .l2: ; set up cl for bit shifts mov cl, 4 ; grab highest nibble from dx mov al, dh ; remove highest nibble from dx shl dx, cl ; shift away second-highest nibble that we accidentally copied shr al, cl ; map 0-9 to ascii codes for '0' to '9' add al, 0x30 ; if result is larger than '9', ... cmp al, 0x3a jl pputc ; ... add 7 so we continue at 'A' add al, 7 pputc: push bx mov ah, 0x0e xor bx, bx int 0x10 pop bx ret