flat assembler
Message board for the users of flat assembler.

Index > DOS > how to convert byte to string ?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
denial



Joined: 12 Sep 2004
Posts: 98
denial
Ok,
I gave it a try, however I got problems. I wrote a routine that converts a byte to a string, that is declared like this:

Code:
_buffer db '0','0','0','$'
    


Here's what I got, it works when I pass one-digit bytes. But when the byte I want to convert has more than one digit, I get fatal errors:

Code:
_byte2string:
        cmp ax,100
        jnb .dth
        cmp ax,10
        jnb .dtt
        jmp .ald
        .dth:
                mov cx,100
                div cx
                add al,48
                mov [bx],al
                inc bx
                movsx ax,ah
        .dtt:
                mov cx,10
                div cx
                add al,48
                mov [bx],al
                inc bx
                movsx ax,ah
        .ald:
                add al,48
                mov [bx],al
        .pts:
                inc bx
                mov [bx],byte '$'
        ret
    


This is, how I call it:

Code:
mov ax,200
mov bx,_buffer
call _byte2string
    


Who can help me? I don't see my mistake Sad
The only problem I could imagine is the movsx part because this doesn't get executed with one-digit-bytes, where the routine works well. But I don't know whats wrong exactly...
Thank you...
Post 04 Sep 2005, 13:58
View user's profile Send private message Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
denial
i think you have over complicated this Smile , some clean short idea, then make it easy.

Code:
org 256

mov ax,$03 ; set video mode ( neccesary in some cases, and for xp )
int 10h

mov al,123 ; parameter
mov si,_string
call byte2string

mov ah,9 ; dos function write $ string
mov dx,_string
int 21h

xor ah,ah ; waitkey
int 16h

int 20h

_string:
db "255$" ; reserve string

byte2string: ; al = input, [ds:si] = output $ terminated
xor ah,ah
add si,2
mov [si+1],byte '$'
mov cx,3
.loop:
xor dx,dx
mov bx,10
div bx
add dl,"0"
mov [si],dl
dec si
loop .loop
ret
    


here is the simple word2string converter....
Code:
org 256

mov ax,$03 ; set video mode ( neccesary in some cases, and for xp )
int 10h

mov ax,12345 ; parameter
mov si,_string
call word2string

mov ah,9 ; dos function write $ string
mov dx,_string
int 21h

xor ah,ah ; waitkey
int 16h

int 20h

_string:
db "65535$" ; reserve more bit "255$" but currently 4 bytes max

word2string: ; ax = input, [ds:si] = output $ terminated
add si,4
mov [si+1],byte '$'
mov cx,5
.loop:
xor dx,dx
mov bx,10
div bx
add dl,"0"
mov [si],dl
dec si
loop .loop
ret

    


hint: you can first make it on paper, think about if you whould be the processor how whould you make it?
Post 04 Sep 2005, 18:20
View user's profile Send private message Visit poster's website Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
denial
Thank you again Smile
I modified your code a bit to avoid the leading zeroes when using _byte2string with a byte containing less than 3 digits.
Besides that I wrote two new functions: _tolower and _strlen. So here I want to present my humble newbie-library. Someone might find it useful Wink

Code:
; turns all lower-case characters into capital letters inside a given string.
; usage: si contains the pointer to the string
_toupper:
        @@:
        cmp [si],byte '$'
        je @f
                cmp [si],byte 97
                jb .con
                cmp [si],byte 122
                ja .con
                sub [si],byte 32
                .con:
                inc si
                jmp @b
        @@:
        ret


; turns all capital letters into lower-case characters inside a given string
; usage: si contains the pointer to the string
_tolower:
        @@:
        cmp [si],byte '$'
        je @f
                cmp [si],byte 65
                jb .con
                cmp [si],byte 90
                ja .con
                add [si],byte 32
                .con:
                inc si
                jmp @b
        @@:
        ret

; counts the length of a string and stores the result in al.
; usage: si contains the pointer to the string
_strlen:
        xor al,al
        @@:
        cmp [si],byte '$'
        je @f
        inc al
        inc si
        jmp @b
        @@:     
        ret


; converts a byte into a string.
; usage: al contains the byte that should be converted
;        si contains the pointer to the string that gets filled.
;                AT LEAST FOUR CHARACTERS!
_byte2string:
        xor ah,ah 

        cmp al,100
        jb @f
        inc si
        @@:
        cmp al,10
        jb @f
        inc si
        @@:

        mov [si+1],byte '$' 
        mov cx,3 
        .loop: 
        xor dx,dx 
        mov bx,10 
        div bx 
        add dl,48
        mov [si],dl 
        dec si 
        loop .loop 
        ret 
    


I tested the routines and they work pretty nice. Output from my program:

Code:
This is our: TeSt-STriNG :O)
After _toupper: TEST-STRING :O)
After _tolower: test-string :o)
And _strlen shows the length of our string: 15
    


Suggestions and further hints are welcome - I wanna learn Smile
Post 04 Sep 2005, 21:17
View user's profile Send private message Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
i see you take the time and not just want to learn,
nice going.

if i can give some code to learn from, you can search my posts,
and not just for codes, maeby you find something useful, ideas, tricks.
i will update some i posted and pack tto library in zip if i have some time, but of course look around for other's codes too.
also i recommend using Ralph Brown s interrupt list for example for bios interrupts - much faster to output string via bios like dos, and more universal, can be used in boot sector too.
keyboard handling is also easy with use of bios int 16h ...
Post 05 Sep 2005, 00:27
View user's profile Send private message Visit poster's website Reply with quote
denial



Joined: 12 Sep 2004
Posts: 98
denial
Thank you again, Matrix.
Yes I already saw some of your posts, also codes how to print strings faster... I'll take a closer look at and try to understand and learn from them.

I also read already some parts of the interrupt list - it will surely be useful cause I want to add some further routines to this library, maybe also for writing to disk and things like that. It is a nice possibility to learn.
I also want to add new string routines like substring, well known from the C++ template library Smile and things like that.

Well, maybe all is newbie-stuff Embarassed , but someone out there might find it useful.
Post 05 Sep 2005, 10:00
View user's profile Send private message Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
i know this is an old subject, i've grabed your source and it works. but i don't understand why....
i know i must be a fool.

heres why:

byte2string:
xor ah,ah ; not sure what xor does. i will have to read up about it
add si,2 ; you add two si i guess its to allow u to add the $ to the end of si?
mov [si+1],byte '$' ;
mov cx,3 ; why place 3 into cx? what does cx do in this function (are they functions in assembly?
.loop: ; label for a loop at least i think thats what it is, in either case i know the loop below jumps back to here
xor dx,dx ; xoring again must read what for
mov bx,10 ; why do u place 10 into bx?
div bx ; div bx, ok i think thats devide bx, by what and why? (i will read up on div
add dl,"0" ; why do u add "0" to dl?
mov [si],dl ; ok so u place dl into si why...
dec si ; then u decrease si by 1 once again why
loop .loop
ret


i've quickly wrote comments on the lines, explaining what i do and do not understand i am a newbie. and am trying to grasp asm. not had much luck so far, but i am sure with time i will get it...

_________________
Regards
Damnation
Post 05 Oct 2005, 13:38
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Code:
xor ah,ah ; xoring something with itself clears it, this is just like "mov ah,0"
add si,2 ;number is calculated from lowest (last) digit, so we skip to end of number, which is 3 chars (at most) long
mov [si+1],byte '$' ;and place '$' afterwards
mov cx,3 ; cx is counter for digits, number will have 3 digits
.loop: ; here is loop to write one digit
xor dx,dx ; clear dx, because "div bx" works like ax = (dx:ax) / bx, dx = (dx:ax) mod bx, (dx:ax) is 32bit number consisting of two 16bit registers, but if dx=0 then it is just ax=ax / bx, dx = ax mod bx
mov bx,10 ; we are dividing by 10 to get one digit 0..9 as remainder (modulo)
div bx ; dx = remainder 0..9, which is one digit to write, ax = number divided by 10
add dl,"0" ; dx contains value 0 to 9, so only it's lower byte (dl) is used. this could be as well "add dx,"0". "0" is added to convert number to ascii char (0 + "0" = "0", 1+"0"="1", 5+"0"=5 etc.)
mov [si],dl ;store one decimal digit at si
dec si ;move one digit back in buffer
loop .loop ;loop will decrease cx and jump to ".loop" if cx is nonzero, so this part after ".label" will repeat 3 times
ret
    

read my tutorial to get the basics of assembly.
Post 05 Oct 2005, 14:48
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
thanx for that, helped alot.

read your tutorial before, guess i'll have another read of it.

one thing i don't get is.

if i do

mov [value], 12345

it works correctly

but if i do somthing like

mov ah, 8
int 21h
mov [value], al

it doesn't display correctly.

any ideas?
as cause i am an utter newbie i have no idea what the problem is.

_________________
Regards
Damnation
Post 05 Oct 2005, 18:48
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
Matrix



Joined: 04 Sep 2004
Posts: 1171
Location: Overflow
Matrix
Damnation wrote:
thanx for that, helped alot.

read your tutorial before, guess i'll have another read of it.

one thing i don't get is.

if i do

mov [value], 12345

it works correctly

but if i do somthing like

mov ah, 8
int 21h
mov [value], al

it doesn't display correctly.

any ideas?
as cause i am an utter newbie i have no idea what the problem is.


so i dont get what is the problem.

this puts 12345 decimal to address [value]
mov [value], 12345

move 8 decimat in ah, call interrupt 21h
mov ah, 8
int 21h

this puts al to address [value]
mov byte [value], al ; since its word it has to be type casted to by compatible with al.


value: dw 0
Post 05 Oct 2005, 20:46
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
please post whole source with problem (but preferably as small as possible Wink ) i don't know what "it doesn't display correctly" means, and i also don't know how you declare "value"

matrix: if "value" is defined as "value: dw 0" then it doesn't have to be size-casted, ":" defines label without any size infos, so size is gotten from size of "al"
Post 05 Oct 2005, 21:22
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
no need to surply source as it pritty much matches what u saw above basically.

if i give a constant value of 12345, i will get 12345 back in the consol.

but if i use the dos interupts to take input of 12345.
i get back somthing stupid like 00183.(or at least thats whats showed in the consol, after going through the word2string thing, if i do do that i get garbage printed)

_________________
Regards
Damnation
Post 06 Oct 2005, 04:56
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
Code:

org 100h

jmp @f
    length      db  ?
    _string1    db  '00000$'
@@:
    

    mov ah, 8
    int 21h
    mov [length], al

    mov si, _string1
    mov ax, word [length]
    call word2string
    
    mov dx, _string1
    mov ah, 9
    int 21h

@@:

int 20h
    


theres the source, nothing special, sorry was cranky @ 6 am : oP
uses the function below.

thanx

_________________
Regards
Damnation
Post 06 Oct 2005, 07:05
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
problem is here: mov ax, word [length]. length is a byte-sized variable, so if you use "word [length]" it will take 2 bytes, one from original "length" and one following it (which is '0' = 40h in this case). you can use
Code:
mov ah,0
mov al,[length]    

which will zero-extend "lengh" to word

also note that int 21h/ah=8 only let's you input one character, so this example will just print ascii code of character you typed. and for that, using byte2string is sufficent.
Post 06 Oct 2005, 09:43
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
i tried the bytetostring, changed the bits that needed.
and i'd put in like 2
then i'd get back 283.

any ideas?

_________________
Regards
Damnation
Post 06 Oct 2005, 12:24
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
after reading correctly i realised that al is used, and seeing as ah, 8 returns the value in al, i was able to remove a few lines of code.

but now i get the ouput "098" a lil confused as to why, and the input was 2.

any ideas ?

Code:
 mov ah, 8
 int 21h
 mov si, _string1
 call byte2string
    
 mov dx, _string1
 mov ah, 9
 int 21h
    

_________________
Regards
Damnation
Post 06 Oct 2005, 17:39
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Code:
org 100h

jmp @f
    _string1    db  '00000$'
@@:

    mov ah, 8
    int 21h

    mov si, _string1
    call byte2string

    mov dx, _string1
    mov ah, 9
    int 21h

    int 20h

byte2string:
xor ah,ah ; not sure what xor does. i will have to read up about it
add si,2 ; you add two si i guess its to allow u to add the $ to the end of si?
mov [si+1],byte '$' ;
mov cx,3 ; why place 3 into cx? what does cx do in this function (are they functions in assembly?
.loop: ; label for a loop at least i think thats what it is, in either case i know the loop below jumps back to here
xor dx,dx ; xoring again must read what for
mov bx,10 ; why do u place 10 into bx?
div bx ; div bx, ok i think thats devide bx, by what and why? (i will read up on div
add dl,"0" ; why do u add "0" to dl?
mov [si],dl ; ok so u place dl into si why...
dec si ; then u decrease si by 1 once again why
loop .loop
ret    

why? this code works (it displays ascii code of pressed key). maybe you was wrong also elsewhere.
Post 06 Oct 2005, 19:26
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
ahh....
i missed out xor ah, ah

that was it. i typed it in, find it easier to learn that way.

i get 050 back which is the ascii code for 2.

now to turn that code into a character : o)


thanx!

_________________
Regards
Damnation
Post 06 Oct 2005, 19:45
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Code:
;ds:si = string with number, ax will contain reult
;note: doesn't check invalid characters in string or overflows
str2w:
mov bx,10
xor ax,ax
.digit:
mov cl,[si]
cmp cl,0 
je .r ;end if no more digits
mul bx ;if some more digits then multiply result by 10
sub cl,'0' ;convert ascii digit to binary one
xor ch,ch  ;zero-extend it to word
add ax,cx ;add to result
inc si ;and move to next digit
jmp .digit
.r:
retn    

not tested, but hopefully should work.
Post 06 Oct 2005, 20:24
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
i will test it i did this:

Code:

  cmp al, 048
    jge process
    
process:
    cmp al, 058
    jge non_numeric
    
    sub al, 048
    


process does the type checking, not finished yet. only checks if the value is too large, need to check if too small.

my code is prefixed by two 0's thats my issue. i will need to resolve that, i still get that though with the _strlen.

and well i guess your function is better. as seeing as (i didn't know this till now so thank you) the dos interupt returns an ascii value into al, i would need to convert that value into a character. so if i was to write a quick bit of code to grab multiple letters (which the one i wrote is extremly slow, basically loops the single char input not so great eh : o/)
i can't have 00A00D00A00M or 001002003004005, as it wouldn't look right hehe.

but thanx for all the help so far. [/code]

_________________
Regards
Damnation
Post 06 Oct 2005, 20:30
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
Damnation



Joined: 08 Sep 2005
Posts: 45
Location: England
Damnation
checked your code doesn't work, but i guess u wrote it on the spot, can't complain, just get garbage spewed at me. but i'll attack the code, see if i can see why. i doubt i can but maybe by luck, i could get it to work. o well all adds to the learning curve
Post 06 Oct 2005, 20:39
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.