flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
AsmGuru62 03 Feb 2012, 14:35
NTDLL (which is loaded with every Windows binary) has sprintf function.
It is probably the best way. Call GetProcAddress first to get its entry point and then just call it with C-calling convention: parameters reversed and caller (YOU) cleans up the stack. I am not sure however, how is DOUBLE passed in this case -- you need to do it in C code and then disassemble it to see how it is done. I assume it is put on stack as 8 bytes, but not sure. Try it with debugger and see how it works. P.S. If I am not too busy today - I will post some code later... |
|||
![]() |
|
NanoBytes 04 Feb 2012, 01:05
Yes, i use that function to convert integers into strings. But I tryed as you said, but I am not sure how to phase a float?
What do I put here? ------v cinvoke wsprintf,String1,'%d',Float1 |
|||
![]() |
|
AsmGuru62 04 Feb 2012, 05:07
I meant sprintf() from NTDLL.
|
|||
![]() |
|
NanoBytes 04 Feb 2012, 05:25
Why didnt this work?
Code: FLD1 MOV [Integer1],4 FIDIV [Integer1] FSTP [Float1] invoke GetProcAddress,<invoke GetModuleHandle,"ntdll.dll">,"sprintf" MOV [Integer1],EAX stdcall [Integer1],String1,"%f",[Float1] _writeStr String1 |
|||
![]() |
|
AsmGuru62 04 Feb 2012, 06:12
I just tried the same - no luck.
It outputs the garbage. Take a look here: http://www.website.masmforum.com/tutorials/fptute/fpuchap6.htm#fbstp Using this you can easily convert the FPU value into string. Or you can simply break the FPU value into INTEGER and FRACTIONAL PART and print first the integer part, then decimal dot '.' and then fractional part. Of course, you need to multiply the fractional part first to your desired precision. For example, if you need 8 digits after the decimal dot - multiply it by 100,000,000. Just do not forget padding zeroes. For example, if you have 45.00000789 and you multiply the fractional part by 100,000,000 - you'll get 789, so if you print it without padding you'll get: 45.789 which is wrong, so watch out for these zeroes. |
|||
![]() |
|
NanoBytes 04 Feb 2012, 06:46
Lol, this one kind of works, it outputs 32.0000
Code: MOV [Integer1],3 FILD [Integer1] FSTP [Float1] invoke sprintf,String1,"%f",0,[Float1] |
|||
![]() |
|
NanoBytes 04 Feb 2012, 06:53
Ok, i figured it out. The variable holding your floating point value ("Float1") has to be a quad word
Code: cinvoke sprintf,String1,"%lf",0,dword[Float1+4] ^ ^ ^ I put carrots under the important parts _________________ He is no fool who gives what he cannot keep to gain what he cannot loose. |
|||
![]() |
|
AsmGuru62 04 Feb 2012, 13:32
I see, but I think that will print only one DWORD part of a QWORD value.
|
|||
![]() |
|
LocoDelAssembly 04 Feb 2012, 16:01
Visual Studio 2010 C++ compiler:
Code: #include "stdafx.h" #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) { 00041000 push ebp 00041001 mov ebp,esp 00041003 and esp,0FFFFFFC0h 00041006 sub esp,13Ch 0004100C mov eax,dword ptr [___security_cookie (43000h)] 00041011 xor eax,esp 00041013 mov dword ptr [esp+138h],eax 0004101A push esi double number64 =(double)rand()/(double)RAND_MAX; 0004101B mov esi,dword ptr [__imp__rand (420A8h)] 00041021 call esi 00041023 mov dword ptr [esp+2Ch],eax 00041027 fild dword ptr [esp+2Ch] 0004102B fdiv qword ptr [__real@40dfffc000000000 (421B8h)] 00041031 fstp qword ptr [esp+30h] float number32 = (float)rand()/(float)RAND_MAX; 00041035 call esi 00041037 mov dword ptr [esp+2Ch],eax 0004103B fild dword ptr [esp+2Ch] char buff[256]; printf("Gonna get the string now (Yeah, this string is only to force to compiler to finish the rand stuff instead of blending it into the sprintf call)\n"); 0004103F mov esi,dword ptr [__imp__printf (420A0h)] 00041045 push offset string "Gonna get the string now (Yeah, "... (420F8h) 0004104A fdiv qword ptr [__real@40dfffc000000000 (421B8h)] 00041050 fstp dword ptr [esp+30h] 00041054 call esi sprintf(buff,"64-bit number: %lf; 32-bit number: %f\n", number64, number32); 00041056 fld dword ptr [esp+30h] 0004105A sub esp,0Ch 0004105D fstp qword ptr [esp+8] 00041061 fld qword ptr [esp+40h] 00041065 lea eax,[esp+48h] 00041069 fstp qword ptr [esp] 0004106C push offset string "64-bit number: %lf; 32-bit numbe"... (4218Ch) 00041071 push eax 00041072 call dword ptr [__imp__sprintf (4209Ch)] printf("%s", buff); 00041078 lea ecx,[esp+50h] 0004107C push ecx 0004107D push offset string "%s" (421B4h) 00041082 call esi return 0; } 00041084 mov ecx,dword ptr [esp+15Ch] 0004108B add esp,20h 0004108E pop esi 0004108F xor ecx,esp 00041091 xor eax,eax 00041093 call __security_check_cookie (4109Ch) 00041098 mov esp,ebp 0004109A pop ebp 0004109B ret |
|||
![]() |
|
AsmGuru62 05 Feb 2012, 00:12
1. I tried exactly this "%lf" format with a double value. Does not work.
2. sprintf() from VS2010 is not the same as from NTDLL. Those are diff. functions. |
|||
![]() |
|
LocoDelAssembly 05 Feb 2012, 02:14
I get "f" as result when I use either "%f" or "%lf". To fix this, rather than using NTDLL's version (which looks as limited as wsprintf is for floating point values and perhaps its use is not so well documented), you could import from MSVCRT.DLL, which has been around for quite a lot of time (since Windows 98 at least).
Code: include 'win32axp.inc' proc start local buff[256]:BYTE, pi:QWORD, one:QWORD invoke GetProcAddress, <invoke GetModuleHandle,"MSVCRT.dll">, "sprintf" finit fldpi fstp [pi] fld1 fstp [one] ccall eax, addr buff, "pi: %lf; one: %lf", double[pi], double[one] invoke MessageBox, 0, addr buff, "test", 0 invoke ExitProcess, 0 endp .end start |
|||
![]() |
|
LocoDelAssembly 05 Feb 2012, 02:24
OK I found the format specifications: http://msdn.microsoft.com/en-us/library/aa246400%28v=vs.60%29.aspx
So, %lf is unnecessary (and perhaps it is working by miracle), use %f instead. |
|||
![]() |
|
NanoBytes 05 Feb 2012, 17:13
%g works better. This is because if you want it to convert 1.3, it will give you 1.3000000, but %g will truncate all of the zeros
|
|||
![]() |
|
avcaballero 09 Feb 2012, 15:58
I don't know if I'm late, but here my version goes.
You only need definitions: http://www.abreojosensamblador.net/Productos/AOE/html/Pags_en/Chap01.html#Reales Then, start writing code. I have proved some numbers, I hope it works... sorry if not, I didn't have much time to did it. BTW, it is DOS based. Quote:
Regards
_________________ Siempre aprendiendo |
|||||||||||
![]() |
|
NanoBytes 10 Feb 2012, 03:13
Wow, that is pretty cool, but I was hoping for a windows based one. anyway i figured it out, but thanks for the effort and work you put into this
|
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.