flat assembler
Message board for the users of flat assembler.
Index
> Main > Converting Binary result to ASCII for display |
Author |
|
revo1ution 14 May 2011, 03:15
For binary 0000 to 1001 (0 to 9) add 30h => 30h to 39h (ASCII "0" to "9")
For binary 1010 to 1111 (A to F ) add 37h => 41h to 46h (ASCII "A" to "F") Then combine nibbles into bytes, bytes into words etc. |
|||
14 May 2011, 03:15 |
|
keantoken 14 May 2011, 07:11
OMG!!! It compiles!!!
It's not attached to anything yet, but I wrote this little loop to convert multi-character numbers to ASCII. It took me hours. I'm not sure but maybe I got some operands source-dest swapped. EDIT: I forgot to add, the base it is converted to is not fixed; I think anything below base 11 will work, and with some modifications, up to base 36... Code: Base dd 10 Decimal dd ? Result dd 4096 String dd ? Start: mov ebx, [Base] mov [Decimal], ebx Mainloop: mov ebx, [Decimal] cmp [Result], ebx ;Is the result greater than 10? jge Carry ;If so, move the decimal mov eax, [Result] div [Decimal] add eax, 30h ;Convert to ASCII push eax ;Stack this character cmp [Decimal], ebx ;Have we reached the ones-place yet? je Return ;If so, terminate. mov eax, [Decimal] div [Base] ;Raise decimal again mov [Decimal], eax jmp Mainloop Carry: mov eax, [Decimal] mul [Base] ;Lower the decimal mov [Decimal], eax ;Reinstate the Decimal jmp Mainloop Return: ret One problem though, I didn't realize I wanted the output to be a string in memory, not on the stack. I've been looking at the FASM manual, but the string operations are a bit cryptic to me. How do I insert the characters into the String variable one at a time without simply overwriting the last one? Does this even make sense? Thanks, - keantoken |
|||
14 May 2011, 07:11 |
|
JohnFound 14 May 2011, 07:31
As a rule, the complex string operations needs some library. You may check Fresh IDE project. There are many examples and extended string library with many useful procedures.
|
|||
14 May 2011, 07:31 |
|
keantoken 14 May 2011, 07:54
Actually I just discovered your Fresh program right before I posted here. Unfortunately I'm running Fasmw on WINE, and Fresh doesn't work so well in WINE. If you want I can give you the console output (errors and stuff)(often for WINE you can just install a few native windows DLLs and things will work, trick is finding out which ones it needs). Even so I'm glad to see it; I will probably be using it when I can.
- keantoken |
|||
14 May 2011, 07:54 |
|
JohnFound 14 May 2011, 11:51
keantoken, I am using Fresh with Wine (Ubuntu) without any problems. The only features not working are to run properly native Linux applications (because it was intended to use andLinux for this task)
Anyway, you are not limited to use Fresh IDE. The sources of examples and the libraries are useful with FASMW and any other version of FASM. Of course you can just use them as a template for copy/paste the code you need. Also you might want to to see FreshLib. It is in development now, but already useful, especially for memory/data/strings functions. The additional advantage is that it is freely portable, so your applications could be compiled for Win32 and Linux without changes in the source. In Reference manual for FreshLib you can read how to setup FASMW or FASM environment variables in order to use FreshLib with your projects. |
|||
14 May 2011, 11:51 |
|
keantoken 15 May 2011, 03:23
Which version of WINE do you use? I'm running Ubuntustudio with Wine 1.3.8.
My understanding is that when I use this line: Code: String dd ? I create a memory space I can access using [String]. As I understand it the space will automatically grow as I enter a string into it. Does it work like the stack then? Or must I use another number to address which section of it I need? |
|||
15 May 2011, 03:23 |
|
keantoken 15 May 2011, 03:56
Or does that only apply to the db and du directives?
|
|||
15 May 2011, 03:56 |
|
JohnFound 15 May 2011, 09:01
keantoken wrote: Which version of WINE do you use? I'm running Ubuntustudio with Wine 1.3.8. andLinux and wine 1.0.1 in windows and probably higher version in Ubuntu - in both Fresh IDE works pretty well, although little bit slow. Quote: My understanding is that when I use this line: No, you are wrong. The above line will allocate only 4 bytes and they will not grow when you put data there. The same is valid for every data definition directives. The processor does not understand memory management. Dynamic memory allocations are managed by a library, that allocates one big chunk of memory and then gives to the clients some pieces of it. In Windows there are several API functions that provides such service - like HeapAlloc /HeapFree In Linux you have to use libc or to write your own dynamic memory manager. |
|||
15 May 2011, 09:01 |
|
keantoken 16 May 2011, 03:54
Thanks, I misinterpreted part of the manual. My calculator told me that the largest 32-bit number can take up no more than 10 characters in base-10, so I defined a 10-Dword data area which I will place the number in.
I wouldn't post this except I can't figure this out at all. I used the div operator twice in Mainloop. No matter what I do, I can't get the divide-by-zero errors to stop. The second div operator in fact can't possibly divide by zero, since the operand is specified as non-zero in memory. I checked with OllyDbg and I still can't see where any divide-by-zero could have happened. Code: ; Template for program using standard Win32 headers format PE GUI 4.0 entry start include 'win32w.inc' section '.text' code readable executable start: invoke GetModuleHandle,0 mov [wc.hInstance],eax invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc test eax,eax jz error invoke CreateWindowEx,0,_class,_title,WS_VISIBLE+WS_DLGFRAME+WS_SYSMENU,128,128,800,192,NULL,NULL,[wc.hInstance],NULL test eax,eax jz error msg_loop: invoke GetMessage,msg,NULL,0,0 cmp eax,1 jb error je end_loop jg msg_loop invoke TranslateMessage,msg invoke DispatchMessage,msg jmp msg_loop error: invoke PeekMessage,msg,NULL,0,0,0 push edi push esi mov edi, clcks mov esi, msg ;On error, display msg string in error message movsd pop esi pop edi invoke MessageBox,NULL,[clcks],NULL,MB_ICONERROR+MB_OK end_loop: invoke ExitProcess,[msg.wParam] proc WindowProc uses eax ebx edx ecx esi edi, hwnd,wmsg,wparam,lparam cmp [wmsg],WM_DESTROY je .wmdestroy jmp .rdtsc ;;; .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .finish .wmdestroy: invoke PostQuitMessage,0 xor eax,eax .finish: ret [b] .rdtsc: ; xor eax,eax ;start of my code cpuid rdtsc mov [Time1], eax cpuid rdtsc mov [Time2], eax sub eax, [Time1] mov [Result], eax .Start: mov eax, [Base] .Mainloop: cmp [Result], eax ;Is the result greater than 10? jge .Carry ;If so, move the decimal mov eax, [Result] div [Decimal] ;Mysterious divide-by zeros here add eax, 30h ;Convert to ASCII mov [StringPointer], eax ;String this character add [StringPointer], 4 mov eax, [Base] cmp [Decimal], eax ;Have we reached the ones-place yet? je .Return ;If so, terminate. mov eax, [Decimal] div [Base] ;Raise decimal again. Mysterious divide-by-zeros here mov [Decimal], eax jmp .Mainloop .Carry: mul [Base] ;Lower the decimal mov [Decimal], eax ;Reinstate the Decimal jmp .Mainloop .Return: invoke MessageBox,NULL,[String],_die,MB_OK+MB_ICONEXCLAMATION+MB_SYSTEMMODAL ;display number of processor cycles in message box jmp .defwndproc endp section '.data' data readable writeable _class TCHAR 'FASMWIN32',0 _title TCHAR 'yeahyeahyeah',0 _error TCHAR 'Startup failed.',0 _die TCHAR 'DIED!',0 _bye TCHAR 'bye',0 clcks dd 0 Time1 dd 0 Time2 dd 0 Base dd 1001b Decimal dd 10 Result dd 4096 String rd 10 StringPointer dd String wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,_class msg MSG section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' |
|||
16 May 2011, 03:54 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.