assembler - jak wyswietlic pi albo inna liczbe rzeczywista w messagebox

0

Witam,

Jak mogę wyświetlić obliczoną przez koprocesor liczbę w messageboxie w FASMie? Np. takie coś:

FINIT
        FILD [liczba_b]
        FDIV [liczba_a]
        FCHS
        FSTP [wynik]

invoke MessageBox,[hwnddlg],????,tytulok,MB_OK+MB_ICONWARNING

Prośba o pomoc :)

dodanie znacznika <code class="asm"> - fp

0

• albo jak @kAzek powiedział, użyć jednej z wielu funkcji z zewnętrznych bibliotek (WinAPI albo C-Runtime), albo
• napisać konwersję floata na stringa samemu w asemblerze – do tego będzie potrzebna znajomość budowy liczby zmiennoprzecinkowej (nauka się przyda!), albo
• znaleźć w Google gotowca.

0

Użyłem funkcji wsprintf:

; example of simplified Windows programming using complex macro features

include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here


.code

  start:
        invoke wsprintf, strLiczba,5,"%1.3f",fLiczba
        invoke  MessageBox,HWND_DESKTOP,strLiczba,invoke GetCommandLine,MB_OK
        invoke  ExitProcess,0

strLiczba: times 8 db 0
fLiczba dw 3.12323
.end start

Jednak po kompilacji i uruchomieniu programu wywala błąd, że program .exe przestał działać.

0

Bo podałeś źle parametry (powinien być buffor, format, liczba) ale i tak ja trochę namieszałem zapomniałem że służąca niby do formatowania funkcja wsprintf nie formatuje liczb zmiennoprzecinkowych (w odróżnieniu od strintf z C).

0

Tylko, że nawet jak robię w/w funkcję dla liczby dziesiętnej np. 34

; example of simplified Windows programming using complex macro features

include 'win32ax.inc' ; you can simply switch between win32ax, win32wx, win64ax and win64wx here

.code

  start:

        invoke wsprintf,strLiczba,"%d",35
        invoke  MessageBox,HWND_DESKTOP,strLiczba,"Title",MB_OK
        invoke  ExitProcess,0

strLiczba: times 5 db 0

.end start

Również łapie zawieche i przestaje działać. Chciałbym zrozumieć w czym tkwi problem :P

0

ten wsprintf przyjmuje stringa w Unicode UTF-16 i do takiego też konwertuje.

użyj sprintf z msvcrt.dll

0

Nadal mi wywala błąd podczas działania programu. W opisie błędu jest podana nazwa modułu z błędem 'msvcrt.dll'. Będę wdzięczny jak mi ktoś w tym pomoże. Przykład:

format PE GUI 4.0
entry start
 
include 'win32a.inc'
 
ID_CAPTION         = 101
ID_MESSAGE1         = 102
ID_MESSAGE2         = 103
ID_MESSAGE3         = 104
ID_ICONERROR       = 201
ID_ICONINFORMATION = 202
ID_ICONQUESTION    = 203
ID_ICONWARNING     = 204
ID_TOPMOST         = 301
 
section '.text' code readable executable
 
  start:
 
        invoke  GetModuleHandle,0
        invoke  DialogBoxParam,eax,37,HWND_DESKTOP,DialogProc,0
        or      eax,eax
        jz      exit

  exit:
        invoke  ExitProcess,0
 
proc DialogProc hwnddlg,msg,wparam,lparam
        push    ebx esi edi
        cmp     [msg],WM_INITDIALOG
        je      .wminitdialog
        cmp     [msg],WM_COMMAND
        je      .wmcommand
        cmp     [msg],WM_CLOSE
        je      .wmclose
        xor     eax,eax
        jmp     .finish
  .wminitdialog:
 
        jmp     .processed
  .wmcommand:
        cmp     [wparam],BN_CLICKED shl 16 + IDCANCEL
        je      .wmclose
        cmp     [wparam],BN_CLICKED shl 16 + IDOK
        jne     .processed
 
        xor eax,eax
        invoke  GetDlgItemInt,[hwnddlg],ID_MESSAGE1,NULL,TRUE
        mov [liczba_a],eax
        invoke GetDlgItemInt,[hwnddlg],ID_MESSAGE2,NULL,TRUE
        mov [liczba_b],eax
        invoke GetDlgItemInt,[hwnddlg],ID_MESSAGE3,NULL,TRUE
        mov [liczba_c],eax
        xor eax,eax

        mov eax,[liczba_a]
        cmp eax,0
        je .blad

        FINIT
        FILD [liczba_b]
        FDIV [liczba_a]
        FCHS
        FSTP [wynik]


        invoke sprintf,strZmienna,"%d",liczba_a
        invoke MessageBox,[hwnddlg],"lala",tytulwynik,MB_OK+MB_ICONINFORMATION



        jmp .processed

  .blad:
        invoke MessageBox,[hwnddlg],bladtekst,tytulok,MB_OK+MB_ICONWARNING
        jmp .processed
 
  .wmclose:
        invoke  EndDialog,[hwnddlg],0
  .processed:
        mov     eax,1
  .finish:
        pop     edi esi ebx
        ret
endp
 
section '.bss' readable writeable
 
  flags dd ?
  caption rb 40h
  wynik1 db 'X1+X2= '
   wynik2 db 'X1X2= ',0
  wynik dd 54

  liczba_a dd 0
  liczba_b dd 0
  liczba_c dd 0
  bladtekst db 'Wspolczynnik a musi byc rozny od 0!',0
  tytulok db 'Blad',0
  tytulwynik db 'Wynik',0
  formacik db " \n %d"
  strZmienna: times 5 db 0
 
section '.idata' import data readable writeable
 
  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          msvcrt,'msvcrt.DLL'
 
  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         ExitProcess,'ExitProcess'
 
  import user,\
         DialogBoxParam,'DialogBoxParamA',\
         CheckRadioButton,'CheckRadioButton',\
         GetDlgItemInt,'GetDlgItemInt',\
         IsDlgButtonChecked,'IsDlgButtonChecked',\
         MessageBox,'MessageBoxA',\
         EndDialog,'EndDialog',\
         wsprintf,'wsprintfA'

  import msvcrt,\
         sprintf,'sprintf'
 
section '.rsrc' resource data readable
 
  directory RT_DIALOG,dialogs
 
  resource dialogs,\
           37,LANG_ENGLISH+SUBLANG_DEFAULT,demonstration
 
  dialog demonstration,'Wzory Viete''a',70,70,190,78,WS_CAPTION+WS_POPUP+WS_SYSMENU+DS_MODALFRAME
    dialogitem 'STATIC','&Dany jest wielomian ax^2+bx+c. Podaj',-1,30,10,134,134,WS_VISIBLE
    dialogitem 'STATIC','&Wspolczynnik a: ',-1,10,30,70,8,WS_VISIBLE
    dialogitem 'EDIT','',ID_MESSAGE1,70,30,15,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'STATIC','&Wspolczynnik b: ',-1,10,45,70,8,WS_VISIBLE
    dialogitem 'EDIT','',ID_MESSAGE2,70,45,15,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'STATIC','&Wspolczynnik c: ',-1,10,60,70,8,WS_VISIBLE
    dialogitem 'EDIT','',ID_MESSAGE3,70,60,15,13,WS_VISIBLE+WS_BORDER+WS_TABSTOP
    dialogitem 'BUTTON','OK',IDOK,130,30,45,15,WS_VISIBLE+WS_TABSTOP+BS_DEFPUSHBUTTON
    dialogitem 'BUTTON','C&ancel',IDCANCEL,130,50,45,15,WS_VISIBLE+WS_TABSTOP+BS_PUSHBUTTON
 
  enddialog
0

msvcrt używa konwencji cdecl, a nie stdcall jak większość windowsowych bibliotek.
nie wiem jak to zrobić w FASM-ie, ale prawdopodobnie to invoke musiałbyś zamienić na serię pushów i call.

0

Wywala się bo 2 argument funkcji sprintf nie kończy się null. Weź zmienną tak jak masz ten formacik tylko zakończ null

formacik db "%d", 0
invoke sprintf,strZmienna, formacik, [liczba_a]
invoke MessageBox,[hwnddlg], strZmienna,tytulwynik,MB_OK+MB_ICONINFORMATION

1 użytkowników online, w tym zalogowanych: 0, gości: 1