I'm compiling the following code:
#include <stdio.h>
#include <stdint.h>
uint32_t fibonacci(uint32_t pos) {
long next = 1, current = 0, tmp;
for (long n = 1; n <= pos; n++) {
tmp = current;
current = next;
next += tmp;
}
return current;
}
int main() {
uint32_t target_pos, result;
scanf("%u", &target_pos);
result = fibonacci(target_pos);
printf("%u\n", result);
return 0;
}
Which results in the following assembly code:
0000000000001189 <fibonacci>:
1189: endbr64
118d: push %rbp
118e: mov %rsp,%rbp
1191: mov %edi,-0x24(%rbp)
1194: movq $0x1,-0x20(%rbp)
119c: movq $0x0,-0x18(%rbp)
11a4: movq $0x1,-0x10(%rbp)
11ac: jmp 11cb <fibonacci+0x42>
11ae: mov -0x18(%rbp),%rax
11b2: mov %rax,-0x8(%rbp)
11b6: mov -0x20(%rbp),%rax
11ba: mov %rax,-0x18(%rbp)
11be: mov -0x8(%rbp),%rax
11c2: add %rax,-0x20(%rbp)
11c6: addq $0x1,-0x10(%rbp)
11cb: mov -0x24(%rbp),%eax
11ce: cmp %rax,-0x10(%rbp)
11d2: jle 11ae <fibonacci+0x25>
11d4: mov -0x18(%rbp),%rax
11d8: pop %rbp
11d9: retq
Now, I did some research and this is what I have:
- The first instruction (endbr64) is security-related [ref], and in my case it will be a NOP
- The instructions 0x118d, 0x118e, 0x11d8 and 0x11d9 are related to the return [ref]
%rbpis the base of the stack
With that information, we have this diagram:
I've tried to understand it, but some operations are completely nonsense:
%eax(that for what I've found it's used for returning data) gets saved (not loaded) unchanged%ediis loaded at the start, and it doesn't change/get queried from that pointThe asm performs a "variable++" on
-0x10(%rbp); so you expect that in-0x10(%rbp)n, that is the only variable that gets incremented by 1, is stored. But in one instruction%raxgets compared "less than or equal" with-0x10(%rbp)(looking at the original C code, I assume that the asm is doingpos <= n, when it should be the other way)
And like that more and more...
Someone can explain me what the hell is happening? I've compiled the C code with an AMD 3950X without optimizations.

mov %edi,-0x24(%rbp)means move edi to the memory address 0x24 after rbp. Which would make sense, since edi is the first parameter (pos). If you prefer reading intel syntax (and what logical person doesn't?), tell your disassembler that that's what you want.-M intelis not the default option inobjdump?... That's most likely the whole problem that I had, just switching things around... Thanks @DavidWohlferd for your help!-masm=intelisn't the default forgcc; GAS's AT&T syntax came first, support for it's flavour of Intel syntax was only added years later. Blame AT&T at Bell Labs for their early Unix assembler inventing its own syntax that's somewhat like PDP-11.