flat assembler
Message board for the users of flat assembler.
Index
> Main > Basic arithmetic | Integer to string conversion |
Author |
|
AsmGuru62 06 Dec 2011, 18:19
You need to convert the result from a register (say EAX) into a string, which can be shown in a dialog. It is done by a function wsprintf(), which comes as import from USER32.DLL. Also, your code is responsible for cleaning the stack after the call.
Code: strFormat db 'THE RESULT IS: %d',0 strTitle db 'RESULT OF ADDITION',0 strBuffer rb 64 ... mov eax, 53627 add eax, 73893 invoke wsprintf, strBuffer, strFormat, eax add esp, 3*4 invoke MessageBox, 0, strBuffer, strTitle, MB_OK |
|||
06 Dec 2011, 18:19 |
|
LocoDelAssembly 06 Dec 2011, 19:07
Code: invoke wsprintf, strBuffer, strFormat, eax add esp, 3*4 Code: cinvoke wsprintf, strBuffer, strFormat, eax ; Notice the leading c AsmGuru62's code is fine and there is no reason not to use it, but still for exercising purposes I'd recommend you try to port itoa to Assembly (although not necessarily exactly as it appears, just something that produces the same string as output). |
|||
06 Dec 2011, 19:07 |
|
AsmGuru62 06 Dec 2011, 21:14
Yep! cinvoke is better - less lines.
|
|||
06 Dec 2011, 21:14 |
|
flat_fiat 06 Dec 2011, 22:08
AsmGuru62 wrote: ... Also, your code is responsible for cleaning the stack after the call. Thanks. One more question...since my program terminates immediately after showing the sum, there's no need for me to clean up the stack, right? When Windows terminates the process all allocated memory my program was using is freed. Am I thinking of this correctly? |
|||
06 Dec 2011, 22:08 |
|
Tyler 06 Dec 2011, 22:25
Yes. All the memory gets freed when the program terminates and there's no need to worry about cleaning the stack, since all the memory is freed. (Not that cleaning the stack is the same as freeing other memory.)
|
|||
06 Dec 2011, 22:25 |
|
AsmGuru62 07 Dec 2011, 15:12
If you put that code (where you invoke wsprintf) into a separate procedure, then you do need to clean the stack. But in that specific case above - no need.
|
|||
07 Dec 2011, 15:12 |
|
DOS386 12 Dec 2011, 02:31
> sub [result],48
ADD maybe ??? Also ZERO-terminate the string. > You need to convert the result from a register (say EAX) into a string, > which can be shown in a dialog. It is done by a function wsprintf() Or write your own or find one http://board.flatassembler.net/topic.php?t=9494 "number_to_string_dec" |
|||
12 Dec 2011, 02:31 |
|
LocoDelAssembly 12 Dec 2011, 03:37
Quote:
No, notice that both operands are characters so by subtracting he gets the correct answer (also null terminated since he works with the entire dword). Obviously this doesn't work if the result cannot be represented in a single decimal digit. |
|||
12 Dec 2011, 03:37 |
|
Overflowz 12 Dec 2011, 07:48
Code: mov eax,'1' ;EAX = 31 add eax,'2' ;EAX = 31+32=63 so, numbers are from 30 to 39 (in ASCII) you should first convert it to decimal, add them together and then convert again to ascii. |
|||
12 Dec 2011, 07:48 |
|
flat_fiat 12 Dec 2011, 19:29
AsmGuru62 wrote: You need to convert the result from a register (say EAX) into a string, which can be shown in a dialog. It is done by a function wsprintf().... While I was pondering this function, I was thinking "...Why do I need to manually specify the buffer?...That seems like it could be bad...Wouldn't it be better if the function took care of that automatically?..." So I looked up the function in Microsoft's MSDN and sure enough, they recommend not using it and instead using alternatives such as StringCbPrintf. So my question is, why was wsprintf implemented the way it was as opposed to other functions like StringCbPrintf, which appear to be a better (as in safer) way of doing things? I guess wsprintf was a general 'do-it-all' function whereas the others like StringCbPrintf are much more narrow in scope? |
|||
12 Dec 2011, 19:29 |
|
bdo1964 12 Dec 2011, 22:52
here is an example
Code: include 'win32a.inc' format PE console 4.0 entry start ;********************************************* section '.data' data readable writeable ;********************************************* v1 db '999999999999999999',0 v2 db '000099999999999999',0 ;must have same len as v1!!! ; ^^^^ <-left pad with zero's!!! vv db '0000000000000000000',0 ;<-vv must have len v1+1!!! tit db 'v1+v2=' x dd 0 ; v1+v2 = 1000099999999999998 ;********************************************* nl db 0 _s db '%s',13,0 _i db '%i',13,0 _x db '%08X ',13,0 ;********************************************* section '.text' code readable executable ;********************************************* proc strlen stdcall str:dword xor ecx,ecx xor eax,eax mov ebx,[str] strlen_loop: mov al,byte[ebx] cmp al,0 jz strlen_is_null_byte inc ecx inc ebx jmp strlen_loop strlen_is_null_byte: xor eax,eax mov eax,ecx ret endp ;********************************************* start: ;fasm_bn_add.fasm stdcall strlen,v1 ;note: only v1's length is determined mov ecx,eax ;therefore v2 must have the same length ;thus we would left pad v2 with zero's xor eax,eax xor ebx,ebx add_digits: xor eax,eax mov ah,byte[v1+ecx-1] add al,byte[v2+ecx-1] and ax,$0f0f mov bh,ah add bh,al add bh,bl ;bh=ah+al+carry(bl) mov byte[x],bl mov byte[x],bh cmp bh,10 jb zero_carry ;carry(bl)=1 mov bl,1 sub bh,10 jmp past_zero_carry zero_carry: mov bl,0 past_zero_carry: or bh,$30 mov byte[vv+ecx],bh dec ecx jnz add_digits cmp bl,1 jb no_final_carry mov byte[vv],$31 no_final_carry: ;********************************************* ; invoke MessageBox,0,vv,tit,0 cinvoke printf,_s,vv;vv = 1000099999999999998 invoke ExitProcess,0 ;*********************************************** section '.idata' data import readable writeable library kernel32,'kernel32.dll',\ user32,'user32.dll',\ msvcrt,'msvcrt.dll' include 'api\kernel32.inc' include 'api\user32.inc' import msvcrt,\ printf,'printf' ;*********************************************** _________________ briano Last edited by bdo1964 on 15 Dec 2011, 05:34; edited 2 times in total |
|||
12 Dec 2011, 22:52 |
|
DOS386 13 Dec 2011, 09:02
> No, notice that both operands are characters so by subtracting
Damn |
|||
13 Dec 2011, 09:02 |
|
revolution 13 Dec 2011, 09:11
flat_fiat wrote: So my question is, why was wsprintf implemented the way it was as opposed to other functions like StringCbPrintf, which appear to be a better (as in safer) way of doing things? I guess wsprintf was a general 'do-it-all' function whereas the others like StringCbPrintf are much more narrow in scope? |
|||
13 Dec 2011, 09:11 |
|
AsmGuru62 13 Dec 2011, 18:08
M$ recommends not to use these functions because today's coders are way too primitive and their code is easily "buffer overflowable"!
|
|||
13 Dec 2011, 18:08 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.