flat assembler
Message board for the users of flat assembler.
Index
> DOS > how to convert byte to string ? Goto page 1, 2 Next |
Author |
|
Matrix 04 Sep 2005, 18:20
denial
i think you have over complicated this , 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? |
|||
04 Sep 2005, 18:20 |
|
denial 04 Sep 2005, 21:17
Thank you again
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 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 |
|||
04 Sep 2005, 21:17 |
|
Matrix 05 Sep 2005, 00:27
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 ... |
|||
05 Sep 2005, 00:27 |
|
denial 05 Sep 2005, 10:00
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 and things like that. Well, maybe all is newbie-stuff , but someone out there might find it useful. |
|||
05 Sep 2005, 10:00 |
|
Damnation 05 Oct 2005, 13:38
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 |
|||
05 Oct 2005, 13:38 |
|
vid 05 Oct 2005, 14:48
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. |
|||
05 Oct 2005, 14:48 |
|
Damnation 05 Oct 2005, 18:48
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 |
|||
05 Oct 2005, 18:48 |
|
Matrix 05 Oct 2005, 20:46
Damnation wrote: thanx for that, helped alot. 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 |
|||
05 Oct 2005, 20:46 |
|
vid 05 Oct 2005, 21:22
please post whole source with problem (but preferably as small as possible ) 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" |
|||
05 Oct 2005, 21:22 |
|
Damnation 06 Oct 2005, 04:56
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 |
|||
06 Oct 2005, 04:56 |
|
Damnation 06 Oct 2005, 07:05
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 |
|||
06 Oct 2005, 07:05 |
|
vid 06 Oct 2005, 09:43
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. |
|||
06 Oct 2005, 09:43 |
|
Damnation 06 Oct 2005, 12:24
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 |
|||
06 Oct 2005, 12:24 |
|
Damnation 06 Oct 2005, 17:39
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 |
|||
06 Oct 2005, 17:39 |
|
vid 06 Oct 2005, 19:26
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. |
|||
06 Oct 2005, 19:26 |
|
Damnation 06 Oct 2005, 19:45
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 |
|||
06 Oct 2005, 19:45 |
|
vid 06 Oct 2005, 20:24
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. |
|||
06 Oct 2005, 20:24 |
|
Damnation 06 Oct 2005, 20:30
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 |
|||
06 Oct 2005, 20:30 |
|
Damnation 06 Oct 2005, 20:39
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
|
|||
06 Oct 2005, 20:39 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.