В момента се опитвам да придобия опит с извикването на асемблиращи функции от C. Затова създадох малка програма, която изчислява сумата на всички елементи на масива.
C кодът изглежда така:
#include <stdio.h>
#include <stdint.h>
extern int32_t arrsum(int32_t* arr,int32_t length);
int main()
{
int32_t test[] = {1,2,3};
int32_t length = 3;
int32_t sum = arrsum(test,length);
printf("Sum of arr: %d\n",sum);
return 0;
}
И функцията за сглобяване изглежда така:
.text
.global arrsum
arrsum:
pushq %rbp
movq %rsp, %rbp
pushq %rdi
pushq %rcx
movq 24(%rbp),%rcx
#movq 16(%rbp),%rdi
xorq %rax,%rax
start_loop:
addl (%rdi),%eax
addq $4,%rdi
loop start_loop
popq %rcx
popq %rdi
movq %rbp , %rsp
popq %rbp
ret
Предположих, че C се подчинява на конвенцията за извикване и избутва всички аргументи в стека. И наистина, на позиция 24(%rbp) мога да намеря дължината на масива. Очаквах да намеря указателя към масива на 16(%rbp), но вместо това просто намерих 0x0. След известно отстраняване на грешки открих, че C изобщо не натиска указателя, а вместо това премества целия указател в регистъра %rdi.
Защо това се случва? Не можах да намеря информация за това поведение.