Page 1 of 2

Uppercase and lowercase output in Hex to string function

Posted: Fri Jun 22, 2012 2:53 am
by phillid
Hi, I've recently written a function for my OS that converts a hex number to a string. Here it is:

Code: Select all

HexToString:
	mov		di, HexNumberBuffer
	xor		ah, ah					; zero-out ah so shifiting doesn't cause bits of ah to come into al
	push	ax						; save AL
	shr		al, 4					; Shift AL along 4 bits
	add		al, 48d					; add 48 onto it
	cmp		al, 57d					; see if it's > 9
	jg		.letter
.return:
	stosb
	pop		ax
	shl		al, 4
	shr		al, 4
	add		al, 48d
	cmp		al, 57d
	jg		.letter_last_digit
	stosb
.quit:
	ret

.letter:
	add		ax, 7d
	jmp		.return

.letter_last_digit:
	add		ax, 7d
	stosb
	jmp		.quit
(obviously I've not finished commenting but that's another story)

However, if I load AL with 0x2B, I get the string '2B' in my output buffer but if I load al with 0x2b, I get '2b' in the output buffer. The case of the letter(s) in the hex value are reflected in the string!
How is this possible?! Aren't 0x2B and 0x2b stored as the exact same thing?

Someone please point out why this is happening :)

Re: Uppercase and lowercase output in Hex to string function

Posted: Fri Jun 22, 2012 3:44 am
by AndrewBuckley
im a rookie and my eyes glaze over reading assembly, but how are you storing a hex number if its not already a string? if im understanding whats happening correctly, your getting two different values because "0x2B" != "0x2b".

should your code not just increment the string(hex) pointer by 2 bytes to clear out the 0x ?

Re: Uppercase and lowercase output in Hex to string function

Posted: Fri Jun 22, 2012 4:25 am
by phillid
Haha ok :D
No, in the case of assembly, a hex number is a number, not a string. You can load a register with a value in any form - binary, decimal, hexadecimal, octal, etc, etc. Just because it's got letters in it doesn't mean it's a string :) In this case it just another digit in the hex numbering system.
In this case 0x2b should equal 0x2B because I'm storing the actual hex number, not a string.
As far as the '0x' goes, that's just what people tack onto the beginning to denote that it's a hex number.

So can anyone answer my question, please? :D

Re: Uppercase and lowercase output in Hex to string function

Posted: Fri Jun 22, 2012 5:49 am
by Nable
Too many magic constants.

Code: Select all

hex2str:
    mov edi, buffer
    mov ecx, 8 ; number of hex digits
    mov ebx, eax
.next_digit:
    rol ebx, 4
    mov eax, ebx
    and eax, 0xF ; select 4 bits
    add eax, '0'
    cmp eax, '9'
    jb  @f
    add eax, 'A'-'0'-10
@@:
    stosb
    loop .next_digit
    ret
Also, i even tried your code, it outputs upper-cased letters as expected. Are you trolling here?

Re: Uppercase and lowercase output in Hex to string function

Posted: Fri Jun 22, 2012 8:29 am
by Combuster
Nable wrote:Are you trolling here?
Given a random other thread, yes.

Re: Uppercase and lowercase output in Hex to string function

Posted: Fri Jun 22, 2012 4:23 pm
by phillid
No, I am NOT trolling. I'm seriously weirded-out by this. How is my computer doing this?! NASM would store 2B and 2b as the same thing, right?

And what other thread?

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 12:49 am
by iansjack
Your code doesn't put anything in the output buffer so whatever is in it when the routine ends is just what you put in it to start with. This is a stupid question which you could easily have solved just by looking at the code or by using a debugger.

Until you learn how to debug code you will get nowhere.

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 2:02 am
by phillid
iansjack wrote:Your code doesn't put anything in the output buffer so whatever is in it when the routine ends is just what you put in it to start with.
Wrong, I use stosb to store AL at ES:DI. ES was set to the correct segment outside of the function and DI was set to the address of my buffer at the start of the function.

iansjack wrote:Until you learn how to debug code you will get nowhere.
As I have written my entire OS project in assembly so far (not to mention numerous other projects), I don't think you realise the time I do actually spend debugging each night. When working on my OS, about 99% of my time is spend debugging and 0.5% coding (and 0.5% getting coffees).

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 2:35 am
by AndrewBuckley
There has been a miscommunication on this tread, mostly my fault of lazyness at a late hour. This has made me out to look like an idiot. While i could let it go, this is indeed the internet, so I won't. Computers don't store hex values, they store binary. They have operations that work on integers of various sizes. Hexidecimal is a 4 bit to one character representation used to better read those integers, which is usually represented as ascii strings (2 + (bits long / 4) + null).

Code: Select all

mov al, 0x2B
mov al, 0x2b
mov al, 43d
mov al, '+'
all do the same thing in your assembler, but the computer will only see it as 43d in register al.

when I hear you have a value as hexidecimal, I assumed you had a string that began with '0','x' and following that, only had values from (0 to 9)||('A' to 'Z')||(''a to 'z'), obviously assuming things did not work out for me. My only recommendation is to change HexToString to something like RegALtoHex or something.


Now I am curious, I took the time to look at the code now, and looking at it seems to make sense to me. iansjack said nothing gets put into the output buffer,but would stosb not be what does that? was this code retconned at any point?

EDIT: ninja'd with OPs response to iansjack on the stosb

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 2:36 am
by iansjack
Your code didn't show ES being set so we can't tell that the result is being stored in the buffer; you don't show the state of the direction flag either. You need to post all relevant code, not just snippets.

My other comment stands - use a debugger and you will soon see where you are going wrong. Clearly the code, as presented, would not give the results that you describe so you are not telling us some vital information. A debugger will reveal that and it's your place to investigate it not our's to guess.

Edit: The more I look at your code the messier it appears; I'm very surprised that it even produces the results that you report. Single-step through it in a debugger; it will be an education for you.

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 3:39 am
by Solar
Generally, before asking a question on a piece of code, one should make sure that:
  • the code presented is all that is required to reproduce the described behaviour (i.e., complete); yet
  • is no longer than absolutely necessary (i.e. minimal).
The idea is that you don't present people with your dysfunctional video driver, or file system driver, or scheduler, but with a snippet of code that you would expect to do X but that does something else.

This gives you good chances of finding the error yourself while you are trying to find the minimal set, it proves to people that you did all you could to find the error yourself, and it makes it much easier for people to pinpoint the error.

Ref. Machete Debugging.

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 5:24 am
by iansjack
I'd suggest that the state of the DF flag (not to mention the contents of %ES) is relevant information in this case. Also the way that the function is being called as the reported results are clearly nonsense. It looks to me as if that string is being put into the buffer manually and is then never changed; that's really the only hypothesis that makes any sense. And it is a hypothesis that the OP could easily test with a debugger.

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 12:42 pm
by Kazinsal
phillid wrote:As I have written my entire OS project in assembly so far (not to mention numerous other projects), I don't think you realise the time I do actually spend debugging each night. When working on my OS, about 99% of my time is spend debugging and 0.5% coding (and 0.5% getting coffees).
Then you are doing something horribly wrong. My OS crud is in assembly as well, and I'll usually spend about a fifth of the time debugging and four-fifths coding. Methinks you need to learn to write more solid code.

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 1:22 pm
by iansjack
As I have written my entire OS project in assembly so far (not to mention numerous other projects), I don't think you realise the time I do actually spend debugging each night. When working on my OS, about 99% of my time is spend debugging and 0.5% coding (and 0.5% getting coffees).
I can only suggest that you haven't really got the hang of debugging yet (and a 1% efficiency rate in your code production seems alarmingly low!). This is such a simple routine that it should be trivial to debug. It has to be obvious by just single-stepping through the code where the error lies. How long can that take?

BTW, no-one has asked yet how you put the values in %al in the first place. How are you doing it that lets you put 0x2B or 0x2b in the register?

Re: Uppercase and lowercase output in Hex to string function

Posted: Sat Jun 23, 2012 3:47 pm
by phillid
@Merlin, I understand that and thus I was blown away when the computer running my OS seemingly magically knew the case of letters in the hex value I had in my source code.

ES and other segment registers are set upon entry. I am sure they are not changed as my functions that use STOSB and LODSB continue to function correctly.

Code: Select all

mov		ax, cs
mov		ds, ax
mov		es, ax
mov		ss, ax
The direction flag shouldn't have any effect, should it? The function stores my hex values, except it somehow knows the case of the letters in the values I put in the source code. Nevertheless, it is clear.

I must admit that the 1% and 99% was a hyperbole.