Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

jim bob

Assembly question...

This topic is 6125 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I realize this may not be the perfect place to ask (as compared to maybe an x86 assembly forum), but I thought I could give it a go. I am trying to write an inline assembly code block (Intel syntax, x86) to convert a byte, word, or even a doubleword value, stored either in a variable or in a register, to a string that I can print out. This is more for debugging purposes. Debug.com, when using the "r" switch, can display the contents of all the registers in hex numbers. This is what I would like to do. For example: - move variable or immediate value into DX - - convert the value in DX into a string of hex numbers - - display the string of hex numbers on the screen - I keep trying lots of things. However, I either end up displaying a lot of other memory along with the number that I don''t need, or I display the number''s actual ASCII hex symbol, not the numbers in hex form. I hope you understand what I mean. Any help or ideas is appreciated. Thanks so much. I am not worthy of a sig!

Share this post


Link to post
Share on other sites
Advertisement
I''m not really programming in assembly anymore now (well except for my ti calculator, z80 assembly ), but I think this is a way how it can be done.

mov bx, 4 ; 4 * 4 bits, counter

nextdigit:
mov ax, dx
and ax, $f

; you have the hexadecimal digit stored in ax (0 - 15). You could use a lookup table (with the string 0123456789ABCDEF in it), and convert the number to an ascii character. I''m not sure how to put this on the screen however.

mov cl, 4
shr dx, cl

dec bx
cmp bx, 0
jnz nextdigit:

Note that this is 16bit assembly, but converting it to 32bit shouldn''t be that hard. Also note that the rightmost digit will be printed first, then the digits left from it. One way to get the less significant digit at the right side, you could put the al value each time in a sort of array that will hold the digits(at position bx, which is the counter). Then you can use int 21 (the dos interrupt I think, but I''m not sure) to display this array at the cursor position.

Share this post


Link to post
Share on other sites
There''s a very quick way to do this... the method eludes me though...

Well, this is hiw MSVC implements it:
  
static void __cdecl xtoa (
unsigned long val,
char *buf,
unsigned radix,
int is_neg
)
{
char *p; /* pointer to traverse string */
char *firstdig; /* pointer to first digit */
char temp; /* temp char */
unsigned digval; /* value of digit */

p = buf;

if (is_neg) {
/* negative, so output ''-'' and negate */
*p++ = ''-'';
val = (unsigned long)(-(long)val);
}

firstdig = p; /* save pointer to first digit */

do {
digval = (unsigned) (val % radix);
val /= radix; /* get next digit */

/* convert to ascii and store */
if (digval > 9)
*p++ = (char) (digval - 10 + ''a''); /* a letter */
else
*p++ = (char) (digval + ''0''); /* a digit */
} while (val > 0);

/* We now have the digit of the number in the buffer, but in reverse
order. Thus we reverse them now. */

*p-- = ''\0''; /* terminate string; p points to last digit */

do {
temp = *p;
*p = *firstdig;
*firstdig = temp; /* swap *p and *firstdig */
--p;
++firstdig; /* advance to next two digits */
} while (firstdig < p); /* repeat until halfway */
}

/* Actual functions just call conversion helper with neg flag set correctly,
and return pointer to buffer. */


char * __cdecl _itoa (
int val,
char *buf,
int radix
)
{
if (radix == 10 && val < 0)
xtoa((unsigned long)val, buf, radix, 1);
else
xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
return buf;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
i''ve just written this now so i dont know if its exactly correct but i think the comments are enough, this will convert a number in ax to any base specified in bx, it will store the answer as a null terminated string starting at address in di it can easily be converted to 32 bit assembly. it is NOT the fastest way to do this but i didn''t think speed would be important.

mov ax,[value] ;put the value to be converted in ax
mov bx,16 ;you are interested in hex
mov cx,0 ;characters on stack

loop: div bx ;remainder now in dx
add dx,48 ;convert to ascii
cmp dx,57 ;if greater than ''9'' add another 7
jle charOkay
add dx,7
charOkay: push dx ;add character to stack
inc cx
cmp ax,0 ;is ax 0, have we finished?
jne loop ;if not keep going

mov di,buffer ;where to put string
cld ;make sure were going forwards
loop2: pop dx ;get character
stosb ;store character
dec cx ;have we finished
jcxz loop2 ;if not repeat
mov ax,0 ;null terminator
stosb

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!