My problem is that I don't understand what starts happening in the stack from line 27. <br(The code is compiled on godbolt.org) <br<br<brBelow I will give part of the code in assembler and C <brAssembler: <br<br<br
calc_integ: pushq %rbp movq %rsp, %rbp addq $-128, %rsp movq %rdi, -88(%rbp) movl $0, -44(%rbp) fldz fstpt -16(%rbp) fldt .LC1(%rip) fstpt -64(%rbp) fildl -44(%rbp) fldt -64(%rbp) fsubp %st, %st(1) fildq -88(%rbp) cmpq $0, -88(%rbp) jns .L2 fldt .LC2(%rip) faddp %st, %st(1) .L2: fdivrp %st, %st(1) fstpt -80(%rbp) fildl -44(%rbp) fstpt -32(%rbp) movq $0, -40(%rbp) jmp .L3 .L4: pushq -24(%rbp) <- This is where I don't understand pushq -32(%rbp) call sinl addq $16, %rsp fstpt -112(%rbp) pushq -24(%rbp) pushq -32(%rbp) call expl addq $16, %rsp fldt -112(%rbp) fmulp %st, %st(1) fstpt -112(%rbp) fldt -32(%rbp) fldt -80(%rbp) faddp %st, %st(1) leaq -16(%rsp), %rsp fstpt (%rsp) call sinl addq $16, %rsp fstpt -128(%rbp) fldt -32(%rbp) fldt -80(%rbp) faddp %st, %st(1) leaq -16(%rsp), %rsp fstpt (%rsp) call expl addq $16, %rsp fldt -128(%rbp) fmulp %st, %st(1) fldt -112(%rbp) faddp %st, %st(1) fldt -16(%rbp) faddp %st, %st(1) fstpt -16(%rbp) fldt -32(%rbp) fldt -80(%rbp) faddp %st, %st(1) fstpt -32(%rbp) addq $1, -40(%rbp) .L3: movq -40(%rbp), %rax cmpq -88(%rbp), %rax jb .L4 fldt -16(%rbp) fldt -80(%rbp) fmulp %st, %st(1) fstpt -16(%rbp) fldt -16(%rbp) fldt .LC3(%rip) fdivrp %st, %st(1) fstpt -16(%rbp) fldt -16(%rbp) leave ret
c:
long double calc_integ(unsigned long N) { int a = 0; long double integral = 0; long double b = M_PI; long double step = (b - a) / N; long double point = a; for (size_t k = 0; k < N; k++) { integral += sinl(point)*expl(point) + sinl(point + step)*expl(point + step); //<- this //corresponds to the 27th line of assembler code point += step; } integral *= step; integral /= 2; return integral; } int main() { struct timespec sts, stf; unsigned long int N = 0; scanf("%ld", &N); clock_gettime(CLOCK_REALTIME, &sts); printf("%lf", calc_integ(N)); clock_gettime(CLOCK_REALTIME, &stf); printf("Program execution time: %lf ", stf.tv_sec - sts.tv_sec + 0.000000001 * (stf.tv_nsec - sts.tv_nsec)); return 0; }
Can you please give me a hint or a direction that will help me figure it out, I don’t even know how to google it.
How I reasoned:
- Added a value from -24(%rbp) to the top of the stack. But there is garbage stored there, because I drew the stack and nothing is put at this address.
- then copy the value of the point to the top of the stack
- call the sinl function, which takes the element from the top of the stack as an argument, that is point. And its return value sinl will be saved in the address where the garbage was previously stored. The same thing happens with exp.But then I see the multiplication of st(1) and st. The only thing that can be multiplied here is sinl and exp. But how did these values get into fpu?I have an assumption that the return values of the functions sinl and exp are saved in fpu. But then, what happens on the stack?