I need to make a routine that will convert a memory address into a string of bytes. That string would then be the input for a function that prints null-terminated strings (which I was already able to make). For example, if I have an address 0x1bf9 I need to print the text "1bf9" to the screen. The book hasn't gone into 32 bit mode yet, but it kind of hinted that we would need it for that too. This is what I have so far:
TABLE:
db "0123456789ABCDEF", 0
STRING:
db 0
hex_to_char:
lea bx, TABLE
mov ax, dx
mov ah, al ;make al and ah equal so we can isolate each half of the byte
shr ah, 4 ;ah now has the high nibble
and al, 0x0F ;al now has the low nibble
xlat ;lookup al's contents in our table
xchg ah, al ;flip around the bytes so now we can get the higher nibble
xlat ;look up what we just flipped
inc STRING
mov [STRING], ah ;append the new character to a string of bytes
inc STRING
mov [STRING], al ;append the new character to the string of bytes
ret
Hex numbers are generally always represented with a leading 0x , so you'd use 0xFFFFFFBB .
Assembly language has no direct means of printing anything. Your assembler may or may not come with a library that supplies such a facility, otherwise you have to write it yourself, and it will be quite a complex function. You also have to decide where to print things - in a window, on the printer?
Software developers and system designers widely use hexadecimal numbers because they provide a human-friendly representation of binary-coded values. Each hexadecimal digit represents four bits (binary digits), also known as a nibble (or nybble).
This attempts to increment a literal label, which isn't correct. Also, your STRING memory location only allocates one byte (char) instead of a larger number to accommodate the size of string you intend.
STRING:
db 0
inc STRING ;THIS WON'T WORK
mov [STRING], ah ;append the new character to a string of bytes
inc STRING ;THIS WON'T WORK
mov [STRING], al ;append the new character to the string of bytes
A neutral comment: the character table used for xlat
does not need to be zero terminated.
Also I'd recommend saving and restoring some registers as good asm programming practice. That way, the calling function doesn't need to worry about registers being changed "behind its back". Ultimately then, you probably want something like this:
TABLE:
db "0123456789ABCDEF", 0
hex_to_char:
push bx
mov bx, TABLE
mov ax, dx
mov ah, al ;make al and ah equal so we can isolate each half of the byte
shr ah, 4 ;ah now has the high nibble
and al, 0x0F ;al now has the low nibble
xlat ;lookup al's contents in our table
xchg ah, al ;flip around the bytes so now we can get the higher nibble
xlat ;look up what we just flipped
mov bx, STRING
xchg ah, al
mov [bx], ax ;append the new character to the string of bytes
pop bx
ret
section .bss
STRING:
resb 50 ; reserve 50 bytes for the string
EDIT: some desirable tweaks based upon Peter Cordes' input.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With