[bits 16] ; Prints \r\n using BIOS teletype output print16_newline: push ax mov ah, 0x0e ; bios teletype output mov al, 0x0a ; newline char int 0x10 mov al, 0x0d ; carriage return int 0x10 pop ax ret ; Prints a null-terminated string beginning in the addr in bx print16_string: pusha print16_string_char_loop: mov al, [bx] ; move current value of bx into lower-half of ax cmp al, 0 ; check if char is null je g_return ; if so, end of string, so return ; otherwise, print the character mov ah, 0x0e ; bios teletype output int 0x10 ; Now, advance mem addr of bx by 1 to point to next char add bx, 1 jmp print16_string_char_loop ; Calls print16_string then print16_newline print16: call print16_string call print16_newline ret ; Template for printing hex strings i_print16_hex_template: db '0x0000', 0 ; Prints the value of dx register as a hex-string print16_hex_string: pusha mov cx, 0 ; init looping variable print16_hex_string_loop: cmp cx, 4 ; check if looping is == 4 je print16_hex_string_end ; if so, break the loop mov ax, dx ; copy the hex value to a mutable register and ax, 0x000f ; mask off all but the last bit add al, 0x30 ; convert the number to ASCII 0-9 cmp al, 0x39 ; check if number is 0-9 or a-f jle print16_hex_string_update_template ; if 0-9, no further adding needed add al, 39 ; otherwise, a-f so offset to proper ASCII range print16_hex_string_update_template: mov bx, i_print16_hex_template + 5 ; end of ascii template sub bx, cx ; make bx point to currently-updated char mov [bx], al ; copy ASCII char we computed above into current position of bx shr dx, 4 ; shift dx over 1 byte so we can compute next char add cx, 1 ; increment looping var jmp print16_hex_string_loop print16_hex_string_end: mov bx, i_print16_hex_template ; copy the filled-out template addr to bx call print16_string ; print it out jmp g_return ; Calls print16_hex_string then print16_newline print16_hex: call print16_hex_string call print16_newline ret