我想在Linux中使用匯編代碼計算sin(x)
(使用「泰勒展開」)。sin(x)的彙編代碼
6
A
回答
7
這篇文章對您有幫助嗎?
http://www.coranac.com/2009/07/sines/
它有一對夫婦的算法用於計算近似的sin(x)的值,與C和彙編的版本。當然,這是ARM組裝,但它的要點應該很容易轉換成x86或類似的。
9
你不說明哪個CPU架構,所以我假設x86。
簡單的(也可能是效率最低的)方法是將公式寫入RPN,它可以直接映射到FPU指令。
實施例,
代數公式:X - (!X^3/3)+(!X^5/5)
RPN:XXX * X * 3 2 */- XX * X * X * X * 5 4 * 3 * 2 */+
成爲:
fld x
fld x
fld x
fmul
fld x
fmul
fild [const_3]
fild [const_2]
fmul
fdiv
fsub
fld x
fld x
fmul
fld x
fmul
fld x
fmul
fld x
fmul
fild [const_5]
fild [const_4]
fmul
fild [const_3]
fmul
fild [const_2]
fmul
fdiv
fadd
有一些明顯的優化策略 -
- 代替計算X,X X X, X X X X X等每個術語,存儲 '投放產品' 和只是乘法 由X * X每次
- 代替的 計算階乘每個 來看,做同樣的「運行產品」
下面是針對x86 FPU一些註釋代碼,每個FPU指令之後的評論顯示堆棧狀態後,該指令具有前ecuted,與棧頂(ST0)在左邊,如:
fldz ; 0
fld1 ; 1, 0
--snip--
bits 32
section .text
extern printf
extern atof
extern atoi
extern puts
global main
taylor_sin:
push eax
push ecx
; input :
; st(0) = x, value to approximate sin(x) of
; [esp+12] = number of taylor series terms
; variables we'll use :
; s = sum of all terms (final result)
; x = value we want to take the sin of
; fi = factorial index (1, 3, 5, 7, ...)
; fc = factorial current (1, 6, 120, 5040, ...)
; n = numerator of term (x, x^3, x^5, x^7, ...)
; setup state for each iteration (term)
fldz ; s x
fxch st1 ; x s
fld1 ; fi x s
fld1 ; fc fi x s
fld st2 ; n fc fi x s
; first term
fld st1 ; fc n fc fi x s
fdivr st0,st1 ; r n fc fi x s
faddp st5,st0 ; n fc fi x s
; loop through each term
mov ecx,[esp+12] ; number of terms
xor eax,eax ; zero add/sub counter
loop_term:
; calculate next odd factorial
fld1 ; 1 n fc fi x s
faddp st3 ; n fc fi x s
fld st2 ; fi n fc fi x s
fmulp st2,st0
fld1 ; 1 n fc fi x s
faddp st3 ; n fc fi x s
fld st2 ; fi n fc fi x s
fmulp st2,st0 ; n fc fi x s
; calculate next odd power of x
fmul st0,st3 ; n*x fc fi x s
fmul st0,st3 ; n*x*x fc fi x s
; divide power by factorial
fld st1 ; fc n fc fi x s
fdivr st0,st1 ; r n fc fi x s
; check if we need to add or subtract this term
test eax,1
jnz odd_term
fsubp st5,st0 ; n fc fi x s
jmp skip
odd_term:
; accumulate result
faddp st5,st0 ; n fc fi x s
skip:
inc eax ; increment add/sub counter
loop loop_term
; unstack work variables
fstp st0
fstp st0
fstp st0
fstp st0
; result is in st(0)
pop ecx
pop eax
ret
main:
; check if we have 2 command-line args
mov eax, [esp+4]
cmp eax, 3
jnz error
; get arg 1 - value to calc sin of
mov ebx, [esp+8]
push dword [ebx+4]
call atof
add esp, 4
; get arg 2 - number of taylor series terms
mov ebx, [esp+8]
push dword [ebx+8]
call atoi
add esp, 4
; do the taylor series approximation
push eax
call taylor_sin
add esp, 4
; output result
sub esp, 8
fstp qword [esp]
push format
call printf
add esp,12
; return to libc
xor eax,eax
ret
error:
push error_message
call puts
add esp,4
mov eax,1
ret
section .data
error_message: db "syntax: <x> <terms>",0
format: db "%0.10f",10,0
運行程序:
$ ./taylor-sine 0.5 1
0.4791666667
$ ./taylor-sine 0.5 5
0.4794255386
$ echo "s(0.5)"|bc -l
.47942553860420300027
6
+0
這可能是一個家庭作業練習。 – 2010-11-23 07:18:02
相關問題
- 1. 用於計算sin(x)的68HC11的彙編代碼
- 2. MPLAB X IDE v2.35彙編程序代碼,無法彙編(PIC16F84A)
- 3. 彙編代碼
- 4. iOS彙編代碼
- 5. 彙編代碼MOVS
- 6. C++彙編代碼
- 7. 彙編代碼C
- 8. x86彙編代碼
- 9. ARM彙編代碼
- 10. GMP-彙編代碼?編譯代碼
- 11. 彙編&C - 翻譯C'S代碼彙編
- 12. 反編譯彙編代碼
- 13. FORTRAN中sin()的源代碼
- 14. C++代碼片段的彙編代碼
- 15. C++代碼中的彙編代碼
- 16. IA32彙編代碼Y86彙編代碼:leal指令
- 17. 轉換GCC彙編代碼爲armasm彙編代碼
- 18. 彙編代碼的說明
- 19. 寫彙編代碼的C++
- 20. 彙編代碼的x86
- 21. 彙編代碼的說明
- 22. 彙編代碼的解釋
- 23. 彙編代碼的解釋
- 24. 含義的彙編代碼
- 25. 彙編代碼的幫助
- 26. 彙編代碼到C代碼
- 27. 從C#代碼生成彙編代碼?
- 28. CachedAnonymousMethodDelegate1從代碼反彙編代碼
- 29. Sin迴歸僞代碼
- 30. 使用匯編代碼
個人的朋友做這一次,年前...不好玩 – 2010-11-23 07:17:25