Me gustaría obtener el código de ensamblado para calcular sin(x)
(usando "Taylor Expansion") en Linux.Código de ensamblaje para sin (x)
Respuesta
¿Te puede ayudar este artículo?
http://www.coranac.com/2009/07/sines/
Tiene un par de algoritmos para el cálculo de pecado aproximada (x) los valores, con ambas versiones de montaje C y. De acuerdo, es ensamblado ARM, pero la esencia de esto debería traducirse fácilmente a x86 o similar.
excelente enlace. ¡Gracias! – kenny
Alguien me señala en la dirección de matemáticas para principiantes .. por favor.Ese enlace me está dando pesadillas :) –
@ dark-star1: echa un vistazo a http://khanacademy.org - Hay un conjunto de videos sobre funciones aproximadas a mitad de camino en la lista de Cálculo, y hay videos para cada nivel de matemáticas previos lo. – Cogwheel
No indicas qué arquitectura de CPU, por lo tanto, asumo x86.
La forma simplista (y posiblemente la más ineficiente) sería escribir la fórmula en RPN, que se puede asignar casi directamente a las instrucciones FPU.
ejemplo,
fórmula algebraica: x - (! X^3/3) + (! X^5/5)
RPN: xxx * x * 3 2 */- xx * x * x * x * 5 * 4 * 3 * 2/+
que se convierte en:
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
Hay algunas estrategias de optimización obvias -
- en lugar de calcular x, x x x, x x x x x etc para cada término, almacenar un 'producto correr' y simplemente se multiplican por x * x cada vez
- vez de calcular el factorial para cada plazo, hacer lo mismo 'producto de marcha'
Aquí hay algo de código comentado para x86 FPU, los comentarios después de cada instrucción de FPU mostrar el estado de pila después de que la instrucción tiene ex ecuted, con la parte superior de pila (st0) a la izquierda, por ejemplo:
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
ejecutar el programa:
$ ./taylor-sine 0.5 1
0.4791666667
$ ./taylor-sine 0.5 5
0.4794255386
$ echo "s(0.5)"|bc -l
.47942553860420300027
¿Por qué? Ya existe un código de operación FCOS y FSIN ya que el (alrededor de 1987) procesador fuente 80387
:
http://ref.x86asm.net/coder32.html
Wikipedia
Amigo personal de demoscene
Probablemente sea un ejercicio de tarea. –
- 1. iOS código de ensamblaje
- 2. F # Cómo compilar una cita de código para un ensamblaje
- 3. Código de ensamblaje en C++
- 4. Firmando un ensamblaje sin firmar
- 5. Ingeniería inversa C-código fuente del ensamblaje
- 6. análisis de código estático para lenguaje de ensamblaje
- 7. ¿Hay una convención de código para el ensamblaje (principalmente PIC)?
- 8. Descifrando y comprendiendo el código de ensamblaje
- 9. Ensamblaje de Maven: ensamblaje
- 10. Código fuente para Mac OS X Actualizaciones de Java
- 11. Lenguaje de ensamblaje para principiantes
- 12. ¿Cuál es el problema con mi código de ensamblaje
- 13. ¿Qué significa X en EAX, EBX, ECX ... en el ensamblaje?
- 14. Uso de Qt para dibujar el gráfico de Sin (x)
- 15. .Net: código de ejecución cuando se carga el ensamblaje
- 16. Cómo ejecutar el código de máquina (ensamblaje de aprendizaje)
- 17. line, = plot (x, sin (x)) ¿Qué significa coma?
- 18. Para cada x ... Siguiente vs. Para cada x ... Siguiente x
- 19. Materiales para leer varios lenguajes de ensamblaje?
- 20. Uso de instrucciones SSE con gcc sin ensamblaje en línea
- 21. ¿Cómo obtengo la versión de un ensamblaje sin cargarlo?
- 22. ¿Es posible escribir código de ensamblaje en vb.net o C#?
- 23. cocos2d-x CCTouchDispatcher - sin sharedDispatcher
- 24. Llamar a un servicio WCF sin generar un ensamblaje
- 25. ¿Por qué este código de ensamblaje es más rápido?
- 26. Cargar ensamblaje en AppDomain nuevo sin cargarlo en Parent AppDomain
- 27. ¿Código de ensamblaje x86 más rápido para sincronizar el acceso a una matriz?
- 28. ¿Existen guías buenas, modernas y en línea para la optimización manual del código de ensamblaje?
- 29. Cómo encontrar un método en el código de ensamblaje
- 30. GCC C++ y código de ensamblaje en línea?
hizo esto una vez, hace años ... no es divertido –