Created
October 7, 2014 03:52
-
-
Save jsutlovic/7f1c5629deef4543bb47 to your computer and use it in GitHub Desktop.
Assembly print hex
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[org 0x7c00] | |
mov dx, 0x1fb7 ; Set the value we want to print to dx | |
call print_hex ; Print the hex value | |
jmp $ ; Hang once we're done | |
%include "print_string.asm" | |
; Prints the value of DX as hex. | |
print_hex: | |
pusha ; save the register values to the stack for later | |
mov cx,4 ; Start the counter: we want to print 4 characters | |
; 4 bits per char, so we're printing a total of 16 bits | |
char_loop: | |
dec cx ; Decrement the counter | |
mov ax,dx ; copy bx into ax so we can mask it for the last chars | |
shr dx,4 ; shift bx 4 bits to the right | |
and ax,0xf ; mask ah to get the last 4 bits | |
mov bx, HEX_OUT ; set bx to the memory address of our string | |
add bx, 2 ; skip the '0x' | |
add bx, cx ; add the current counter to the address | |
cmp ax,0xa ; Check to see if it's a letter or number | |
jl set_letter ; If it's a number, go straight to setting the value | |
add byte [bx],7 ; If it's a letter, add 7 | |
; Why this magic number? ASCII letters start 17 | |
; characters after decimal numbers. We need to cover that | |
; distance. If our value is a 'letter' it's already | |
; over 10, so we need to add 7 more. | |
jl set_letter | |
set_letter: | |
add byte [bx],al ; Add the value of the byte to the char at bx | |
cmp cx,0 ; check the counter, compare with 0 | |
je print_hex_done ; if the counter is 0, finish | |
jmp char_loop ; otherwise, loop again | |
print_hex_done: | |
mov bx, HEX_OUT ; print the string pointed to by bx | |
call print_string | |
popa ; pop the initial register values back from the stack | |
ret ; return the function | |
; global variables | |
HEX_OUT: db '0x0000',0 | |
; Padding and magic number | |
times 510-($-$$) db 0 | |
dw 0xaa55 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print_string: ; Push registers onto the stack | |
pusha | |
string_loop: | |
mov al, [bx] ; Set al to the value at bx | |
cmp al, 0 ; Compare the value in al to 0 (check for null terminator) | |
jne print_char ; If it's not null, print the character at al | |
; Otherwise the string is done, and the function is ending | |
popa ; Pop all the registers back onto the stack | |
ret ; return execution to where we were | |
print_char: | |
mov ah, 0x0e ; Linefeed printing | |
int 0x10 ; Print character | |
add bx, 1 ; Shift bx to the next character | |
jmp string_loop ; go back to the beginning of our loop |
I have updated the function here https://gist.github.com/kthompson/957c635d84b7813945aa9bb649f039b9 so that it is not required to reset the HEX_OUT variable each time.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Greetings,
I am new to assembly and I was trying to figure this out, however it seems to me this code skips the first nibble and immediately goes to right shift...
Could someone more knowledgeable than me give me some insight?
Thanks!
p.s. I've already written this code differently and it works without affecting the initial HEX_OUT, I'm asking out of curiosity because I don't want to miss something in this early stage of learning asm...