Передача аргументов определенного размера из C / C ++ в ASM - PullRequest
0 голосов
/ 16 февраля 2019

Из-за технических ситуаций мне нужно смешивать 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), так что ... это смещение данных, и я должен предположить, что оно всегда находится втекущий сегмент данных, как показано во всех примерах, которые я нашел?

Заранее спасибо за ваши комментарии

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...