Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.06.2009, 20:14   #11
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от Max-R Посмотреть сообщение
А как использовать функции С?
в этой небольшой статье в программе для преобразования числа в строку используется функция из библиотеки С wsprintf
rpy3uH вне форума Ответить с цитированием
Старый 16.06.2009, 22:41   #12
Max-R
Пользователь
 
Регистрация: 14.06.2009
Сообщений: 11
По умолчанию

Цитата:
Сообщение от rpy3uH Посмотреть сообщение
в этой небольшой статье в программе для преобразования числа в строку используется функция из библиотеки С wsprintf
Это для фасма? а у меня все прога на тасме. А фасм синтаксис тасма поддерживает?
Max-R вне форума Ответить с цитированием
Старый 17.06.2009, 16:05   #13
Max-R
Пользователь
 
Регистрация: 14.06.2009
Сообщений: 11
По умолчанию

Вот, доделал.
Код:
format pe console
entry begin
include 'C:\asm-all\fasm\include\win32a.inc'
section '.data' data readable writable
f dq ?
m1 dq 2.5066282732 ; sqrt(2*pi)
p dq 0
q dq 0.5
e dq 2.71828183  ; e
fm db '%lf',0; lf аргумент для типа double
section '.code' code readable executable
begin:
      ;---Ввод---
      push f
      push fm
      call [scanf]
      add esp,4*2
;---[x^x+0.5]----
fld qword [f]
fadd [q]
fld qword [f]
call step
;---
fmul [m1]
fst qword [p]
fld qword [f]
FCHS ;смена знака
fld qword [e]
call step
fmul [p]
      ;---Вывод---
      fst qword [f]
      push dword[f+4]
      push dword[f+0]
      push fm
      call [printf]
      add esp,4*3
data    import
        library msvcrt,'msvcrt.dll'
        import  msvcrt,\
                printf,'printf',\
                scanf,'scanf'
        end     data
ret
proc step
                ftst                   ; st0=X=0 ?
                fstsw   ax
                sahf
                jz      @@Zero         ; Да, результат = 0 (CF=NC=0, кстати!)
                mov     bl,ah          ; BL and 1=1 при X<0, 0 при X>0 (исп-ся после получения результата)
                ja      @@PositiveX    ; Если X>0, то никаких проверок нам больше не надо

                fxch                   ; Обмен st0 <-> st1 (st0=Y, st1=X)
                fld     st0          ; st2=st1=X, st1=st0=Y, st0=st0=Y
                frndint                ; st0=Round(st0)=Round(Y)
                fcomp                  ; Сраниваем st0 и st1; st0=st1=Y, st1=st2=X, st3=пусто
                fstsw   ax             ; В AH флаг ZF=ZR=1 при целом Y
                sahf                   ; Y целое?
                jnz     @@Error        ; Нет, отрицательные числа нельзя возводить в нецелую степень!

                fld1
                fld1
                faddp                   ; st2=st1=X, st1=st0=Y, st0=2
                fld     st1          ; st3=st2=X, st2=st1=Y, st1=st0=2, st0=st1=Y
                fprem                  ; st0=st0 mod st1=Y mod 2
                ftst                   ; st0=0 (Y mod 2=0, т.е. чётное) ?
                fstsw   ax             ; В AH флаг ZF=ZR=1 при чётном Y (CF=NC=0, кстати!)
                fstp    st0          ; Удаляем остаток от деления
                fstp    st0         ; Удаляем число 2 (st0), st0=st1=Y, st1=st2=X, st2=пусто
                fxch                   ; Обмен st0 <-> st1 (st0=X, st1=Y)
@@PositiveX:
                fabs                   ; st0=|st0|=|X|
                fyl2x                  ; st0 = st1*log2(st0) = Y*log2(|X|)
                fld     st0         ; st1=st0
                frndint                ; st0=Round(st0)
                fsub    st1,st0    ; st1=st1-st0
                fld1                   ; st1=st0, st0=1
                fscale                 ; st0=st0*2^st1
                fstp    st1          ; Удаляем st1
                fincstp                ; st7=st0, st0=st1
                f2xm1                  ; st0=(2^st0)-1
                fmul    st0,st7    ; st0=st0*st7
                fdecstp                ; st1=st0, st0=st7
                faddp                   ; st0=st0+st1, st0=пусто
                ; Результат в st0 !!!
                test    bl,1           ; X<0 ? (CF=NC=0, кстати!)
                jz      @@End          ; Нет, завершаем
                sahf                   ; Y чётное
                jz      @@End          ; Да, завершаем
                fchs                   ; Если X<0, а Y нечётное, то меняем знак результата
@@End:     ret
@@Error:
                fldz                   ; Заносим 0
                fstp    st1          ; Удаляем X
                stc                    ; CF=CY=1 - ошибка
@@Zero:
                fstp    st1          ; Удаляем Y
                ret                    ; Выходим!
endp
ret
Такой вопрос. Все компилится, считает результат, но потом выскакивает ошибка. Может что-то с выравниванием?
Max-R вне форума Ответить с цитированием
Старый 18.06.2009, 19:43   #14
Max-R
Пользователь
 
Регистрация: 14.06.2009
Сообщений: 11
По умолчанию

Куда же гении ассемблера пропали? Лень чтоли откомпилировать((
Max-R вне форума Ответить с цитированием
Старый 18.06.2009, 20:44   #15
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

Я только добавил ret после add esp,4*3 и все нормально, если не брать, то что она считает с оч. большой погрешностью (~3,33%).
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4

Последний раз редактировалось Goodwin98; 18.06.2009 в 20:49.
Goodwin98 вне форума Ответить с цитированием
Старый 18.06.2009, 20:49   #16
Max-R
Пользователь
 
Регистрация: 14.06.2009
Сообщений: 11
По умолчанию

Цитата:
Сообщение от Goodwin98 Посмотреть сообщение
Я только добавил ret после add esp,4*3 и все нормально(~30%).
Спасибо огромное) А можешь объяснить, почему ошибка была?
Цитата:
Сообщение от Goodwin98 Посмотреть сообщение
она считает с оч. большой погрешностью
Это нормально, такое задание было. Если больше членов брать, будет нормальная точность
Max-R вне форума Ответить с цитированием
Старый 18.06.2009, 20:52   #17
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

Цитата:
А можешь объяснить, почему ошибка была
Да просто ret в данном случае - это выход из программы, а у тебя его, почему то не было.
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4
Goodwin98 вне форума Ответить с цитированием
Старый 18.06.2009, 20:57   #18
Max-R
Пользователь
 
Регистрация: 14.06.2009
Сообщений: 11
По умолчанию

Ясно, он у меня после импорта библиотек был.

А вот такой еще вопрос.
Код:
add esp,4*3
- это выравнивание? а зачем оно нужно? его после push делать надо?
Max-R вне форума Ответить с цитированием
Старый 18.06.2009, 21:05   #19
Goodwin98
equ asm
Участник клуба
 
Аватар для Goodwin98
 
Регистрация: 02.05.2009
Сообщений: 1,605
По умолчанию

Цитата:
это выравнивание? а зачем оно нужно? его после push делать надо?
Обычно, когда ф-ции передаются параметры через стек, то выравнивает его сама ф-ция, но printf, scanf , как и др сишные, к таким не относится. После их вызова стек выравнивать нужно самой программе. Я не помню как такие ф-ции называются, так что все это было "своими словами".
Код:
      push dword[f+4]  ; в стек заносятся 3 параметра, каждый размером 4 байта.
      push dword[f+0]
      push fm
      call [printf]
      add esp,4*3 ; вместо этого можно было бы написать
      ; pop eax
      ; pop eax
      ; pop eax
Какой вопрос - такой ответ. Не забываем пользоваться поиском, гуглом.
Помощь в выполнении работ по ассемблеру ICQ:2725322O4

Последний раз редактировалось Goodwin98; 18.06.2009 в 21:34.
Goodwin98 вне форума Ответить с цитированием
Старый 18.06.2009, 23:52   #20
Max-R
Пользователь
 
Регистрация: 14.06.2009
Сообщений: 11
По умолчанию

Понял, спасибо
Max-R вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск