История изменений
Исправление AlexVR, (текущая версия) :
myfunc.asm:
global myfunc
section .text
myfunc:
mov rax, rdi ; Первый пареметр
add rax, rsi ; Второй параметр
add rax, rdx ; Третий параметр
cqo ; Расширяем RAX до RDX:RAX с учётом знака
mov rcx, 3 ; Делитель в RCX, что бы не сохранять RBX
idiv rcx ; RDX:RAX делим на RCX, частное в RAX (результат), остаток в EDX (побоку)
ret
test.c:
#include <stdio.h>
#include <inttypes.h>
extern int64_t myfunc(int64_t a, int64_t b, int64_t c);
void test_myfunc(int64_t a, int64_t b, int64_t c) {
printf("myfunc(%" PRId64 ", %" PRId64 ", %" PRId64 ")=%" PRId64 "\n", a, b, c, myfunc(a,b,c));
}
int main() {
test_myfunc(1, 2, 3);
test_myfunc(-1,0,1);
test_myfunc(-1,-2,-3);
return 0;
}
Компиляция и сборка:
$ nasm -f elf64 -o myfunc.o myfunc.asm
$ gcc -std=c99 test.c myfunc.o
З.Ы.: Аккуратно смотри под какую платформу компилируешь и пишешь, самое главное понять что есть такое «соглашение о вызове». Это позволит понять в каком порядке передаются параметры, какие регистры можно менять, а какие надо восстановить. Для 64-битных Linux - это System V Application Binary Interface AMD64 Architecture Processor Supplement (на странице 21 про использование регистров).
Исходная версия AlexVR, :
myfunc.asm:
global myfunc
section .text
myfunc:
mov rax, rdi ; Первый пареметр
add rax, rsi ; Второй параметр
add rax, rdx ; Третий параметр
cqo ; Расширяем RAX до RDX:RAX с учётом знака
mov rcx, 3 ; Делитель в RCX, что бы не сохранять RBX
idiv rcx ; RDX:RAX делим на RCX, частное в RAX (результат), остаток в EDX (побоку)
ret
test.c:
#include <stdio.h>
#include <inttypes.h>
extern int64_t myfunc(int64_t a, int64_t b, int64_t c);
void test_myfunc(int64_t a, int64_t b, int64_t c) {
printf("myfunc(%" PRId64 ", %" PRId64 ", %" PRId64 ")=%" PRId64 "\n", a, b, c, myfunc(a,b,c));
}
int main() {
test_myfunc(1, 2, 3);
test_myfunc(-1,0,1);
test_myfunc(-1,-2,-3);
return 0;
}
Компиляция и сборка:
$ nasm -f elf64 -o myfunc.o myfunc.asm
$ gcc -std=c99 test.c myfunc.o
З.Ы.: Аккуратно смотри под какую платформу компилируешь и пишешь, самое главное понять что есть такое «соглашение о вызове». Это позволит понять в каком порядке передаются параметры, какие из них можно менять, а какие надо восстановить. Для 64-битных Linux - это System V Application Binary Interface AMD64 Architecture Processor Supplement (на странице 21 про использование регистров).