В настоящее время я пытаюсь получить некоторый опыт вызова функций сборки из 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.
Почему это происходит? Я не мог найти никакой информации об этом поведении.