Я только начал осваивать сборку. У меня есть последовательность:
- seq (1) = 3;
- seq (2) = 4;
- seq (n) = 0,5 * seq (n-1) + 2 * seq (n-2), dla n> 2;
и оценка должна производиться с двойной точностью
А пока я просто пытаюсь узнать о рекурсивных функциях. Это мой код:
; In the comments, we assume: int *esp;
[bits 32]
; esp -> [ret] ; ret - adres powrotu do asmloader
sub esp, 2*4 ; esp = esp - 8 ; make room for double precision result
; esp ->[ ][ ][ret]
n equ 3
mov ecx, n ; ecx = n = 3
push ecx ; esp -> [ecx][ ][ ][ret] => esp -> [n][ ][ ][ret]
call sequence
addr:
; esp -> [n][ ][ ][ret]
lea eax, [esp+4] ; eax = esp + 4
; eax -> |
; esp -> [n][ ][ ][ret]
fstp qword [eax] ; *(double*)eax <- st = ; fpu store top element
; and pop fpu stack
; st = []
call print
format:
db "seq(%d) = %lf", 0xA, 0
offset equ $ - addr
a dq 3.0
b dq 4.0
y dq 2.0
x dq 0.5
sequence:
; esp ->[addr][n][ ][ ][ret]
finit ; fpu init
mov eax, [esp] ; eax = *(int*)esp = addr
lea eax, [eax+offset] ; eax = eax + offset = st3
cmp ecx, 1 ; ecx - 1 ; ZF affected
jne next1 ; jump if not equal ; jump if ZF = 0
fld qword [eax] ; *(double*)eax = *(double*)a -> st ; fpu load double
; st = [st0] = [*a] ; fpu stack
ret
next1:
cmp ecx, 2 ; ecx - 2 ; ZF affected
jne next2 ; jump if not equal ; jump if ZF = 0
fld qword [eax+8] ; *(double*)eax = *(double*)b -> st ; fpu load double
; st = [st0] = [*b] ; fpu stack
ret
next2:
dec ecx ; ecx = ecx - 1 = 2
dec ecx ; ecx = ecx - 1 = 1
call sequence ; calculate sequence for ECX = 1
; st = [st0] = [*a] ; fpu stack
fld qword [eax+2*8] ; *(double*)eax = *(double*)y -> st ; fpu load double
; st = [st1, st0] = [*y, *a]
fmulp ; st = [st0] = [y*a]
ret
print:
; esp -> [format][n][ ][ ][ret]
call [ebx+3*4] ; printf("seq(%d) = %lf\n", n, *eax);
add esp, 4*4 ; esp = esp + 16
; esp -> [ret]
push 0 ; esp -> [0][ret]
call [ebx+0*4] ; exit(0);
; asmloader API
;
; call [ebx + FUNCTION_NUMBER*4]
;
; FUNCTIONS:
;
; 0 - exit
; 1 - putchar
; 2 - getchar
; 3 - printf
; 4 - scanf
Если n = 1 или n = 2, у меня правильный результат. Но когда у меня n = 3, он выводит: seq (3) = -0.000000, но должно быть 6.000000