将特定大小的参数从C / C ++传递到ASM

时间:2019-02-16 01:18:09

标签: c++ assembly arguments

由于技术原因,我需要将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)如何在64位系统上传递32、16和8位参数?如果我发送较小的数据,它将始终通过64位寄存器发送,而我要做的就是使用所需大小的寄存器RAX,EAX,AX,AL(或其他等效寄存器)?

2)如果我通过_AX寄存器返回结果,如何指定返回值的大小?还是C / C ++程序会根据返回数据的数据类型(int64,int32,int16,int8)自动复制正确的寄存器(RAX / EAX / AX / AL)?

3)此示例从寄存器获取参数。据我在其他示例和帖子中所了解的,只有前(4)个数字参数通过寄存器传递,而其他参数则通过堆栈传递。其他示例直接在返回地址旁边直接从堆栈获取(1st)参数。那么...整个参数集都在堆栈上传递,并且(仅)第一个参数被复制到寄存器中?而且,如果我从堆栈中获取参数,根据系统,它们将始终为64位或32位大小,并且汇编程序应仅从64位值中获取预期的(64/32/16)位大小堆栈?我的意思是,如果我发送一个16位字作为参数,它将始终被推送为64位值,并且汇编程序应该从中提取期望的大小?

4)就与指针的关系而言,据我在示例中所看到和理解的那样,它们作为单个值传递,该值被复制到索引寄存器(如ESI)中,因此...是数据的偏移量和我应该假设它总是驻留在当前的DATA SEGMENT中,如我发现的所有示例所示?

提前感谢您的评论

0 个答案:

没有答案