Из-за технических ситуаций мне нужно смешивать C ++ и Assembly, передавая числовые аргументы и указатели из C ++ в ASM.Я нашел много учебников с очень простыми для понимания примерами и написал некоторый код, чтобы попытаться передать аргументы:
Код сборки (NASM)
; ASSEMBLY FUNCTION
global myFunction
global _myFunction
myFunction:
_myFunction:
mov rax,rdi ; 64 bits
rol rax,2 ; 64 bits
ret
Код C ++
#include <stdio.h>
extern "C" long long myFunction (long long);
int main (void) {
long long x, y;
x = 1;
y = myFunction(x);
printf("1<<2=%ll\n",y);
return 0;
}
Вывод для компиляции и запуска выглядит следующим образом:
[me@localhost ~]$ nasm -f elf64 test_asm.asm
[me@localhost ~]$ g++ -o test test.cpp test_asm.o
[me@localhost ~]$ ./test
1<<2=4
Этот 64-битный код действительно бесполезен, просто использовал его для проверки передачи аргументов, и он работает, как и ожидалось.
Мои сомненияявляются:
1) Как я могу передать 32, 16 и 8-битные параметры в 64-битной системе?Если я отправляю меньшие данные, будут ли они отправляться всегда через 64-битный регистр, и все, что мне нужно сделать, это использовать регистр необходимого размера RAX, EAX, AX, AL (или другие эквивалентные регистры)?
2) Если я верну результат через регистр _AX, как я могу указать размер возвращаемого значения?Или программа C / C ++ автоматически скопирует правильный регистр (RAX / EAX / AX / AL) в соответствии с типом данных (int64, int32, int16, int8) возвращаемых данных?
3) Этот примерполучает параметр из регистра.Насколько я понял из других примеров и постов, только первые (4) числовые аргументы передаются через регистры, а остальные в стеке.Другие примеры получают (1-й) аргумент непосредственно из стека, прямо рядом с адресом возврата.Итак ... ВСЕ стек аргументов передается в стек и (только) первые из них копируются в регистры?И, если я получу параметры из стека, они будут всегда иметь размер 64 или 32 бита в соответствии с системой, и программа сборки должна брать только ожидаемый (64/32/16) размер бита из значения 64-бит встек?Я имею в виду, что если я отправлю 16-битное слово в качестве параметра, оно всегда будет выдвигаться как 64-битное значение, и программа сборки должна извлечь из него только ожидаемый размер?
4) В связи с указателяминасколько я видел и понимал в примерах, они передаются как одно значение, которое копируется в регистр индекса (например, ESI), так что ... это смещение данных, и я должен предположить, что оно всегда находится втекущий сегмент данных, как показано во всех примерах, которые я нашел?
Заранее спасибо за ваши комментарии